From c9652ebf4a275df3fb12b0c67eb1cbe88f9316e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Thu, 6 Jul 2006 16:22:24 +0000 Subject: [PATCH] All values are created in PersistentValue git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1548 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/Threads/Exception.cs | 2 +- .../Project/Src/Threads/Function.cs | 44 ++++--- .../Project/Src/Threads/Thread.cs | 2 +- .../Project/Src/Variables/ArrayValue.cs | 10 +- .../Project/Src/Variables/Evals/Eval.cs | 2 +- .../Project/Src/Variables/ObjectValue.cs | 23 ++-- .../Src/Variables/PersistentCorValue.cs | 34 +++--- .../Project/Src/Variables/PersistentValue.cs | 107 +++++++++++++++++- .../Project/Src/Variables/Value.cs | 70 +----------- .../Project/Src/Variables/Variable.cs | 2 +- 10 files changed, 159 insertions(+), 137 deletions(-) diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs index 08d39d6bd9..d0b5af3da3 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Exception.cs @@ -41,7 +41,7 @@ namespace Debugger this.thread = thread; corValue = thread.CorThread.CurrentException; exceptionType = thread.CurrentExceptionType; - runtimeValue = Value.CreateValue(debugger, corValue); + runtimeValue = new PersistentValue(debugger, corValue).Value; runtimeValueException = runtimeValue as ObjectValue; if (runtimeValueException != null) { while (runtimeValueException.Type != "System.Exception") { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs index 076f59f0de..73882df606 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs @@ -433,21 +433,19 @@ namespace Debugger { return new Variable(debugger, GetParameterName(index), - new PersistentValue(delegate { return GetArgumentValue(index); })); + new PersistentValue(debugger, delegate { return GetArgumentCorValue(index); } )); } - Value GetArgumentValue(int index) + ICorDebugValue GetArgumentCorValue(int index) { - if (this.HasExpired) { - return new UnavailableValue(debugger, "Function has expired"); - } else { - try { - // Non-static functions include 'this' as first argument - return Value.CreateValue(debugger, CorILFrame.GetArgument((uint)(IsStatic? index : (index + 1)))); - } catch (COMException e) { - if ((uint)e.ErrorCode == 0x80131304) return new UnavailableValue(debugger, "Unavailable in optimized code"); - throw; - } + if (this.HasExpired) throw new CannotGetValueException("Function has expired"); + + try { + // Non-static functions include 'this' as first argument + return CorILFrame.GetArgument((uint)(IsStatic? index : (index + 1))); + } catch (COMException e) { + if ((uint)e.ErrorCode == 0x80131304) throw new CannotGetValueException("Unavailable in optimized code"); + throw; } } @@ -488,22 +486,18 @@ namespace Debugger { return new Variable(debugger, symVar.Name, - new PersistentValue(delegate { return GetValueOfLocalVariable(symVar); })); + new PersistentValue(debugger, delegate { return GetCorValueOfLocalVariable(symVar); })); } - Value GetValueOfLocalVariable(ISymUnmanagedVariable symVar) + ICorDebugValue GetCorValueOfLocalVariable(ISymUnmanagedVariable symVar) { - if (this.HasExpired) { - return new UnavailableValue(debugger, "Function has expired"); - } else { - ICorDebugValue corValue; - try { - corValue = CorILFrame.GetLocalVariable((uint)symVar.AddressField1); - } catch (COMException e) { - if ((uint)e.ErrorCode == 0x80131304) return new UnavailableValue(debugger, "Unavailable in optimized code"); - throw; - } - return Value.CreateValue(debugger, corValue); + if (this.HasExpired) throw new CannotGetValueException("Function has expired"); + + try { + return CorILFrame.GetLocalVariable((uint)symVar.AddressField1); + } catch (COMException e) { + if ((uint)e.ErrorCode == 0x80131304) throw new CannotGetValueException("Unavailable in optimized code"); + throw; } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs index 979c80d8f0..e1f1418185 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs @@ -114,7 +114,7 @@ namespace Debugger if (!HasBeenLoaded) throw new DebuggerException("Thread has not started jet"); process.AssertPaused(); - return Value.CreateValue(debugger, corThread.Object); + return new PersistentValue(debugger, corThread.Object).Value; } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs index b2313d434d..162518bf51 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs @@ -109,22 +109,20 @@ namespace Debugger return new Variable(debugger, elementName, - new PersistentValue(delegate { return GetValueOfItem(indices, pValue); })); + new PersistentValue(debugger, delegate { return GetCorValueOfItem(indices, pValue); })); } - Value GetValueOfItem(uint[] indices, PersistentValue pValue) + ICorDebugValue GetCorValueOfItem(uint[] indices, PersistentValue pValue) { ArrayValue updatedVal = pValue.Value as ArrayValue; if (this.IsEquivalentValue(updatedVal)) { - ICorDebugValue element; unsafe { fixed (void* pIndices = indices) { - element = updatedVal.CorArrayValue.GetElement(rank, new IntPtr(pIndices)); + return updatedVal.CorArrayValue.GetElement(rank, new IntPtr(pIndices)); } } - return Value.CreateValue(debugger, element); } else { - return new UnavailableValue(debugger, "Value is not array"); + throw new CannotGetValueException("Value is not array"); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs index a167807c89..8afda9cfb0 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Evals/Eval.cs @@ -168,7 +168,7 @@ namespace Debugger protected internal virtual void OnEvalComplete(bool successful) { // Eval result should be ICorDebugHandleValue so it should survive Continue() - result = Value.CreateValue(debugger, corEval.Result); + result = new PersistentValue(debugger, corEval.Result).Value; debugeeStateWhenEvaluated = debugger.DebugeeState; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs index 8c5f646c12..8e3ab9966b 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs @@ -136,19 +136,16 @@ namespace Debugger field.Name, field.IsStatic, field.IsPublic, - new PersistentValue(delegate { return GetValueOfField(field, pValue); })); + new PersistentValue(debugger, delegate { return GetCorValueOfField(field, pValue); })); } } - Value GetValueOfField(FieldProps field, PersistentValue pValue) + ICorDebugValue GetCorValueOfField(FieldProps field, PersistentValue pValue) { Value updatedVal = pValue.Value; - if (updatedVal is UnavailableValue) return updatedVal; - if (this.IsEquivalentValue(updatedVal)) { - return GetValue(updatedVal, field); - } else { - return new UnavailableValue(debugger, "Object type changed"); - } + if (updatedVal is UnavailableValue) throw new CannotGetValueException(updatedVal.AsString); + if (!this.IsEquivalentValue(updatedVal)) throw new CannotGetValueException("Object type changed"); + return GetCorValue(updatedVal, field); } public IEnumerable GetPropertyVariables(PersistentValue pValue) @@ -205,7 +202,7 @@ namespace Debugger objVal.ClassToken == this.ClassToken; } - Value GetValue(Value val, FieldProps field) + ICorDebugValue GetCorValue(Value val, FieldProps field) { // Current frame is used to resolve context specific static values (eg. ThreadStatic) ICorDebugFrame curFrame = null; @@ -214,15 +211,13 @@ namespace Debugger } try { - ICorDebugValue fieldValue; if (field.IsStatic) { - fieldValue = corClass.GetStaticFieldValue(field.Token, curFrame); + return corClass.GetStaticFieldValue(field.Token, curFrame); } else { - fieldValue = (val.CorValue.CastTo()).GetFieldValue(corClass, field.Token); + return (val.CorValue.CastTo()).GetFieldValue(corClass, field.Token); } - return Value.CreateValue(debugger, fieldValue); } catch { - return new UnavailableValue(debugger); + throw new CannotGetValueException(); } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs index 85b30311ff..24eeb78fb4 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentCorValue.cs @@ -16,19 +16,19 @@ namespace Debugger /// public class PersistentCorValue { - /// - /// Delegate that is used to get value. This delegate may be called at any time and should never return null. - /// - public delegate ICorDebugValue CorValueGetter(); - - NDebugger debugger; - public ICorDebugValue CorValue; + ICorDebugValue corValue; // ICorDebugHandleValue can be used to get corValue back after Continue() public ICorDebugHandleValue corHandleValue; - public PauseSession pauseSessionAtCreation; - public DebugeeState debugeeStateAtCreation; + PauseSession pauseSessionAtCreation; + DebugeeState debugeeStateAtCreation; + + public NDebugger Debugger { + get { + return debugger; + } + } public bool IsExpired { get { @@ -40,19 +40,19 @@ namespace Debugger } } - public ICorDebugValue CorValueProp { + public ICorDebugValue CorValue { get { if (this.IsExpired) throw new DebuggerException("CorValue has expired"); if (pauseSessionAtCreation == debugger.PauseSession) { - return CorValue; + return corValue; } else { if (corHandleValue == null) { throw new DebuggerException("CorValue has expired"); } else { - CorValue = Value.DereferenceUnbox(corHandleValue.As()); + corValue = PersistentValue.DereferenceUnbox(corHandleValue.As()); pauseSessionAtCreation = debugger.PauseSession; - return CorValue; + return corValue; } } } @@ -64,7 +64,7 @@ namespace Debugger if (corHandleValue != null) return corHandleValue; - ICorDebugHeapValue2 heapValue = this.CorValueProp.As(); + ICorDebugHeapValue2 heapValue = this.CorValue.As(); if (heapValue == null) { // TODO: Investigate - hmmm, value types are not at heap? return null; } else { @@ -77,10 +77,8 @@ namespace Debugger { this.debugger = debugger; if (corValue != null) { - if (corValue.Is()) { - corHandleValue = corValue.As(); - } - this.CorValue = Value.DereferenceUnbox(corValue); + this.corHandleValue = corValue.As(); + this.corValue = PersistentValue.DereferenceUnbox(corValue); } this.pauseSessionAtCreation = debugger.PauseSession; this.debugeeStateAtCreation = debugger.DebugeeState; diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs index caab7c6b38..5c599b2772 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs @@ -12,7 +12,10 @@ using Debugger.Wrappers.CorDebug; namespace Debugger { /// - /// PersistentValue is a container used to obtain the value of a given object even after continue. + /// PersistentValue is a container which holds data necessaty to obtain + /// the value of a given object even after continue. This level of + /// abstraction is necessary because the type of a value can change + /// (eg for local variable of type object) /// public class PersistentValue { @@ -21,6 +24,11 @@ namespace Debugger /// public delegate Value ValueGetter(); + /// + /// Delegate that is used to get value. This delegate may be called at any time and should never return null. + /// + public delegate ICorDebugValue CorValueGetter(); + ValueGetter getter; @@ -34,5 +42,102 @@ namespace Debugger { this.getter = getter; } + + public PersistentValue(NDebugger debugger, ICorDebugValue corValue) + { + Value val = CreateValue(debugger, corValue); + this.getter = delegate { return val; }; + } + + public PersistentValue(NDebugger debugger, CorValueGetter corValueGetter) + { + this.getter = delegate { + try { + return CreateValue(debugger, corValueGetter()); + } catch (CannotGetValueException e) { + return new UnavailableValue(debugger, e.Message); + } + }; + } + + internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) + { + if (corValue.Is()) { + int isNull = corValue.CastTo().IsNull; + if (isNull == 0) { + ICorDebugValue dereferencedValue; + try { + dereferencedValue = (corValue.CastTo()).Dereference(); + } catch { + // Error during dereferencing + return null; + } + return DereferenceUnbox(dereferencedValue); // Try again + } else { + return null; + } + } + + if (corValue.Is()) { + return DereferenceUnbox(corValue.CastTo().Object.CastTo()); // Try again + } + + return corValue; + } + + static Value CreateValue(NDebugger debugger, ICorDebugValue corValue) + { + ICorDebugValue derefed = DereferenceUnbox(corValue); + if (derefed == null) { + return new NullValue(debugger, new PersistentCorValue(debugger, corValue)); + } + + CorElementType type = Value.GetCorType(derefed); + + switch(type) + { + case CorElementType.BOOLEAN: + case CorElementType.CHAR: + case CorElementType.I1: + case CorElementType.U1: + case CorElementType.I2: + case CorElementType.U2: + case CorElementType.I4: + case CorElementType.U4: + case CorElementType.I8: + case CorElementType.U8: + case CorElementType.R4: + case CorElementType.R8: + case CorElementType.I: + case CorElementType.U: + case CorElementType.STRING: + return new PrimitiveValue(debugger, new PersistentCorValue(debugger, corValue)); + + case CorElementType.ARRAY: + case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array + return new ArrayValue(debugger, new PersistentCorValue(debugger, corValue)); + + case CorElementType.VALUETYPE: + case CorElementType.CLASS: + case CorElementType.OBJECT: // Short-cut for Class "System.Object" + return new ObjectValue(debugger, new PersistentCorValue(debugger, corValue)); + + default: // Unknown type + return new UnavailableValue(debugger, "Unknown value type"); + } + } + } + + class CannotGetValueException: System.Exception + { + public CannotGetValueException():this("Unable to get value") + { + + } + + public CannotGetValueException(string message):base(message) + { + + } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs index 9b926313ce..c61c51859a 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs @@ -34,7 +34,7 @@ namespace Debugger internal ICorDebugValue CorValue { get { - return pCorValue.CorValueProp; + return pCorValue.CorValue; } } @@ -181,73 +181,5 @@ namespace Debugger if (manType == null) return ""; return manType.ToString(); } - - - internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue) - { - if (corValue.Is()) { - int isNull = corValue.CastTo().IsNull; - if (isNull == 0) { - ICorDebugValue dereferencedValue; - try { - dereferencedValue = (corValue.CastTo()).Dereference(); - } catch { - // Error during dereferencing - return null; - } - return DereferenceUnbox(dereferencedValue); // Try again - } else { - return null; - } - } - - if (corValue.Is()) { - return DereferenceUnbox(corValue.CastTo().Object.CastTo()); // Try again - } - - return corValue; - } - - internal static Value CreateValue(NDebugger debugger, ICorDebugValue corValue) - { - ICorDebugValue derefed = Value.DereferenceUnbox(corValue); - if (derefed == null) { - return new NullValue(debugger, new PersistentCorValue(debugger, corValue)); - } - - CorElementType type = Value.GetCorType(derefed); - - switch(type) - { - case CorElementType.BOOLEAN: - case CorElementType.CHAR: - case CorElementType.I1: - case CorElementType.U1: - case CorElementType.I2: - case CorElementType.U2: - case CorElementType.I4: - case CorElementType.U4: - case CorElementType.I8: - case CorElementType.U8: - case CorElementType.R4: - case CorElementType.R8: - case CorElementType.I: - case CorElementType.U: - case CorElementType.STRING: - return new PrimitiveValue(debugger, new PersistentCorValue(debugger, corValue)); - - case CorElementType.ARRAY: - case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array - return new ArrayValue(debugger, new PersistentCorValue(debugger, corValue)); - - case CorElementType.VALUETYPE: - case CorElementType.CLASS: - case CorElementType.OBJECT: // Short-cut for Class "System.Object" - return new ObjectValue(debugger, new PersistentCorValue(debugger, corValue)); - - default: // Unknown type - return new UnavailableValue(debugger, "Unknown value type"); - } - } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs index b87a74a0c9..2e90c05ad8 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs @@ -98,7 +98,7 @@ namespace Debugger } } - public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(Value.CreateValue(debugger, corValue), name) + public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(new PersistentValue(debugger, corValue).Value, name) { }