Browse Source

PersistentValue stored in Values - lifetime of Values increased

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1551 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 19 years ago
parent
commit
940fd46818
  1. 34
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs
  2. 55
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs
  3. 312
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs
  4. 54
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs
  5. 6
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs
  6. 29
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs
  7. 29
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs
  8. 3
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs

34
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Function.cs

@ -105,27 +105,17 @@ namespace Debugger @@ -105,27 +105,17 @@ namespace Debugger
}
}
}
public Value ThisValue {
ICorDebugValue ThisCorValue {
get {
if (IsStatic) {
throw new DebuggerException("Static method does not have 'this'.");
} else {
if (this.HasExpired) {
return new UnavailableValue(debugger, "Function has expired");
} else {
try {
return new ObjectValue(debugger, new PersistentValue(debugger, CorILFrame.GetArgument(0)), ContaingClass);
} catch (COMException e) {
// System.Runtime.InteropServices.COMException (0x80131304): An IL variable is not available at the current native IP.
// See Forum-8640
if ((uint)e.ErrorCode == 0x80131304) {
return new UnavailableValue(debugger, "Not available in the current state");
} else {
throw;
}
}
}
if (IsStatic) throw new DebuggerException("Static method does not have 'this'.");
if (this.HasExpired) throw new CannotGetValueException("Function has expired");
try {
return CorILFrame.GetArgument(0);
} catch (COMException e) {
// System.Runtime.InteropServices.COMException (0x80131304): An IL variable is not available at the current native IP. (See Forum-8640)
if ((uint)e.ErrorCode == 0x80131304) throw new CannotGetValueException("Not available in the current state");
throw;
}
}
}
@ -383,7 +373,7 @@ namespace Debugger @@ -383,7 +373,7 @@ namespace Debugger
if (!IsStatic) {
yield return new Variable(debugger,
"this",
new PersistentValue(delegate { return ThisValue; }));
new PersistentValue(debugger, delegate { return ThisCorValue; }));
}
foreach(Variable var in ArgumentVariables) {
yield return var;
@ -401,7 +391,7 @@ namespace Debugger @@ -401,7 +391,7 @@ namespace Debugger
get {
// TODO: Should work for static
if (!IsStatic) {
foreach(Variable var in ThisValue.GetSubVariables(new PersistentValue(delegate{return ThisValue;}))) {
foreach(Variable var in new PersistentValue(debugger, delegate{ return ThisCorValue; }).Value.GetSubVariables()) {
yield return var;
}
}

55
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ArrayValue.cs

@ -51,8 +51,9 @@ namespace Debugger @@ -51,8 +51,9 @@ namespace Debugger
public override string AsString {
get {
string txt = "{" + ElementsType + "[";
for (int i = 0; i < rank; i++)
for (int i = 0; i < rank; i++) {
txt += dimensions[i].ToString() + ",";
}
txt = txt.TrimEnd(new char[] {','}) + "]}";
return txt;
}
@ -67,11 +68,21 @@ namespace Debugger @@ -67,11 +68,21 @@ namespace Debugger
lenght = CorArrayValue.Count;
dimensions = new uint[rank];
fixed (void* pDimensions = dimensions)
fixed (void* pDimensions = dimensions) {
CorArrayValue.GetDimensions(rank, new IntPtr(pDimensions));
}
}
bool IsCorValueCompatible {
get {
ArrayValue freshValue = this.FreshValue as ArrayValue;
return freshValue != null &&
freshValue.ElementsType == this.ElementsType &&
freshValue.Lenght == this.Lenght &&
freshValue.Rank == this.Rank;
}
}
public Variable this[uint index] {
get {
return this[new uint[] {index}];
@ -92,11 +103,11 @@ namespace Debugger @@ -92,11 +103,11 @@ namespace Debugger
public Variable this[uint[] indices] {
get {
return GetItem(indices, new PersistentValue(delegate {return this;}));
return GetItem(indices);
}
}
Variable GetItem(uint[] itemIndices, PersistentValue pValue)
Variable GetItem(uint[] itemIndices)
{
uint[] indices = (uint[])itemIndices.Clone();
@ -109,20 +120,14 @@ namespace Debugger @@ -109,20 +120,14 @@ namespace Debugger
return new Variable(debugger,
elementName,
new PersistentValue(debugger, delegate { return GetCorValueOfItem(indices, pValue); }));
new PersistentValue(debugger, delegate { return GetCorValueOfItem(indices); }));
}
ICorDebugValue GetCorValueOfItem(uint[] indices, PersistentValue pValue)
unsafe ICorDebugValue GetCorValueOfItem(uint[] indices)
{
ArrayValue updatedVal = pValue.Value as ArrayValue;
if (this.IsEquivalentValue(updatedVal)) {
unsafe {
fixed (void* pIndices = indices) {
return updatedVal.CorArrayValue.GetElement(rank, new IntPtr(pIndices));
}
}
} else {
throw new CannotGetValueException("Value is not array");
if (!IsCorValueCompatible) throw new CannotGetValueException("Value is not the same array");
fixed (void* pIndices = indices) {
return CorArrayValue.GetElement(rank, new IntPtr(pIndices));
}
}
@ -132,32 +137,22 @@ namespace Debugger @@ -132,32 +137,22 @@ namespace Debugger
}
}
public override IEnumerable<Variable> GetSubVariables(PersistentValue pValue)
public override IEnumerable<Variable> GetSubVariables()
{
uint[] indices = new uint[rank];
while(true) { // Go thought all combinations
for (uint i = rank - 1; i >= 1; i--)
if (indices[i] >= dimensions[i])
{
if (indices[i] >= dimensions[i]) {
indices[i] = 0;
indices[i-1]++;
}
if (indices[0] >= dimensions[0]) break; // We are done
yield return GetItem(indices, pValue);
yield return GetItem(indices);
indices[rank - 1]++;
}
}
public override bool IsEquivalentValue(Value val)
{
ArrayValue arrayVal = val as ArrayValue;
return arrayVal != null &&
arrayVal.ElementsType == this.ElementsType &&
arrayVal.Lenght == this.Lenght &&
arrayVal.Rank == this.Rank;
}
}
}

312
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/ObjectValue.cs

@ -18,54 +18,24 @@ namespace Debugger @@ -18,54 +18,24 @@ namespace Debugger
{
public class ObjectValue: Value
{
ICorDebugClass corClass;
ICorDebugModule corModule;
MetaData metaData;
ICorDebugModule corModuleSuperclass;
ObjectValue baseClass;
Module finalCorClassModule;
uint finalCorClassToken;
Module module;
ICorDebugClass corClass;
TypeDefProps classProps;
public override string AsString {
get {
return "{" + Type + "}";
}
}
public ObjectValue BaseClassObject {
protected ICorDebugObjectValue CorObjectValue {
get {
ObjectValue baseClass = this;
while (baseClass.HasBaseClass) {
baseClass = baseClass.BaseClass;
}
return baseClass;
return this.CorValue.CastTo<ICorDebugObjectValue>();
}
}
IEnumerable<MethodProps> Methods {
get {
return this.Module.MetaData.EnumMethods(this.ClassToken);
}
}
/*
// May return null
public Eval ToStringEval {
public override string AsString {
get {
ObjectValue baseClassObject = this.BaseClassObject;
foreach(MethodProps method in baseClassObject.Methods) {
if (method.Name == "ToString") {
ICorDebugValue[] evalArgs;
ICorDebugFunction evalCorFunction;
baseClassObject.Module.CorModule.GetFunctionFromToken(method.Token, out evalCorFunction);
evalArgs = new ICorDebugValue[] {this.SoftReference};
return new Eval(debugger, evalCorFunction, evalArgs);
}
}
throw new DebuggerException("ToString method not found");
return "{" + Type + "}";
}
}
*/
public override string Type {
get{
@ -75,7 +45,7 @@ namespace Debugger @@ -75,7 +45,7 @@ namespace Debugger
public Module Module {
get {
return debugger.GetModule(corModule);
return module;
}
}
@ -85,24 +55,63 @@ namespace Debugger @@ -85,24 +55,63 @@ namespace Debugger
}
}
internal unsafe ObjectValue(NDebugger debugger, PersistentValue pValue):base(debugger, pValue)
public ObjectValue BaseClass {
get {
ICorDebugClass superClass = GetSuperClass(debugger, corClass);
if (superClass == null) throw new DebuggerException("Does not have a base class");
return new ObjectValue(debugger, pValue, superClass);
}
}
public bool HasBaseClass {
get {
return GetSuperClass(debugger, corClass) != null;
}
}
internal ObjectValue(NDebugger debugger, PersistentValue pValue):base(debugger, pValue)
{
corClass = this.CorValue.CastTo<ICorDebugObjectValue>().Class;
InitObjectVariable();
InitObjectValue(this.CorObjectValue.Class);
}
internal unsafe ObjectValue(NDebugger debugger, PersistentValue pValue, ICorDebugClass corClass):base(debugger, pValue)
internal ObjectValue(NDebugger debugger, PersistentValue pValue, ICorDebugClass corClass):base(debugger, pValue)
{
this.corClass = corClass;
InitObjectVariable();
InitObjectValue(corClass);
}
void InitObjectVariable ()
void InitObjectValue(ICorDebugClass corClass)
{
corModule = corClass.Module;
metaData = Module.MetaData;
classProps = metaData.GetTypeDefProps(corClass.Token);
corModuleSuperclass = corModule;
this.finalCorClassModule = debugger.GetModule(this.CorObjectValue.Class.Module);
this.finalCorClassToken = this.CorObjectValue.Class.Token;
this.module = debugger.GetModule(corClass.Module);
this.corClass = corClass;
this.classProps = Module.MetaData.GetTypeDefProps(corClass.Token);
}
bool IsCorValueCompatible {
get {
ObjectValue freshValue = this.FreshValue as ObjectValue;
return freshValue != null &&
this.finalCorClassModule == freshValue.Module &&
this.finalCorClassToken == freshValue.ClassToken;
}
}
public ObjectValue ObjectClass {
get {
ObjectValue objectClass = this;
while (objectClass.HasBaseClass) {
objectClass = objectClass.BaseClass;
}
return objectClass;
}
}
IEnumerable<MethodProps> Methods {
get {
return this.Module.MetaData.EnumMethods(this.ClassToken);
}
}
public override bool MayHaveSubVariables {
@ -111,24 +120,24 @@ namespace Debugger @@ -111,24 +120,24 @@ namespace Debugger
}
}
public override IEnumerable<Variable> GetSubVariables(PersistentValue pValue)
public override IEnumerable<Variable> GetSubVariables()
{
if (HasBaseClass) {
yield return GetBaseClassVariable(pValue);
yield return GetBaseClassVariable();
}
foreach(Variable var in GetFieldVariables(pValue)) {
foreach(Variable var in GetFieldVariables()) {
yield return var;
}
foreach(Variable var in GetPropertyVariables(pValue)) {
foreach(Variable var in GetPropertyVariables()) {
yield return var;
}
}
public IEnumerable<Variable> GetFieldVariables(PersistentValue pValue)
public IEnumerable<Variable> GetFieldVariables()
{
foreach(FieldProps f in metaData.EnumFields(ClassToken)) {
foreach(FieldProps f in Module.MetaData.EnumFields(ClassToken)) {
FieldProps field = f; // One per scope/delegate
if (field.IsStatic && field.IsLiteral) continue; // Skip field
if (!field.IsStatic && CorValue == null) continue; // Skip field
@ -136,19 +145,32 @@ namespace Debugger @@ -136,19 +145,32 @@ namespace Debugger
field.Name,
field.IsStatic,
field.IsPublic,
new PersistentValue(debugger, delegate { return GetCorValueOfField(field, pValue); }));
new PersistentValue(debugger, delegate { return GetCorValueOfField(field); }));
}
}
ICorDebugValue GetCorValueOfField(FieldProps field, PersistentValue pValue)
ICorDebugValue GetCorValueOfField(FieldProps field)
{
Value updatedVal = pValue.Value;
if (updatedVal is UnavailableValue) throw new CannotGetValueException(updatedVal.AsString);
if (!this.IsEquivalentValue(updatedVal)) throw new CannotGetValueException("Object type changed");
return GetCorValue(updatedVal, field);
if (!IsCorValueCompatible) throw new CannotGetValueException("Object type changed");
// Current frame is used to resolve context specific static values (eg. ThreadStatic)
ICorDebugFrame curFrame = null;
if (debugger.IsPaused && debugger.SelectedThread != null && debugger.SelectedThread.LastFunction != null && debugger.SelectedThread.LastFunction.CorILFrame != null) {
curFrame = debugger.SelectedThread.LastFunction.CorILFrame.CastTo<ICorDebugFrame>();
}
try {
if (field.IsStatic) {
return corClass.GetStaticFieldValue(field.Token, curFrame);
} else {
return CorObjectValue.GetFieldValue(corClass, field.Token);
}
} catch {
throw new CannotGetValueException();
}
}
public IEnumerable<Variable> GetPropertyVariables(PersistentValue pValue)
public IEnumerable<Variable> GetPropertyVariables()
{
foreach(MethodProps m in Methods) {
MethodProps method = m; // One per scope/delegate
@ -157,149 +179,101 @@ namespace Debugger @@ -157,149 +179,101 @@ namespace Debugger
method.Name.Remove(0, 4),
method.IsStatic,
method.IsPublic,
delegate { return CreatePropertyEval(method, pValue); });
delegate { return CreatePropertyEval(method); });
}
}
}
Eval CreatePropertyEval(MethodProps method, PersistentValue pValue)
Eval CreatePropertyEval(MethodProps method)
{
Value updatedVal = pValue.Value;
if (updatedVal is UnavailableValue) {
return null;
}
if (this.IsEquivalentValue(updatedVal)) {
ICorDebugFunction evalCorFunction = Module.CorModule.GetFunctionFromToken(method.Token);
return new Eval(debugger, evalCorFunction, delegate { return GetArgsForEval(method, pValue); });
} else {
return null;
}
}
ICorDebugValue[] GetArgsForEval(MethodProps method, PersistentValue pValue)
{
ObjectValue updatedVal = pValue.Value as ObjectValue;
if (this.IsEquivalentValue(updatedVal)) {
if (method.IsStatic) {
return new ICorDebugValue[] {};
} else {
if (updatedVal.SoftReference != null) {
return new ICorDebugValue[] {updatedVal.SoftReference.CastTo<ICorDebugValue>()};
} else {
return new ICorDebugValue[] {updatedVal.CorValue};
}
}
} else {
return null;
}
}
public override bool IsEquivalentValue(Value val)
{
ObjectValue objVal = val as ObjectValue;
return objVal != null &&
objVal.ClassToken == this.ClassToken;
if (!IsCorValueCompatible) return null;
ICorDebugFunction evalCorFunction = Module.CorModule.GetFunctionFromToken(method.Token);
return new Eval(debugger, evalCorFunction, delegate { return GetArgsForEval(method); });
}
ICorDebugValue GetCorValue(Value val, FieldProps field)
ICorDebugValue[] GetArgsForEval(MethodProps method)
{
// Current frame is used to resolve context specific static values (eg. ThreadStatic)
ICorDebugFrame curFrame = null;
if (debugger.IsPaused && debugger.SelectedThread != null && debugger.SelectedThread.LastFunction != null && debugger.SelectedThread.LastFunction.CorILFrame != null) {
curFrame = debugger.SelectedThread.LastFunction.CorILFrame.CastTo<ICorDebugFrame>();
}
if (!IsCorValueCompatible) return null;
try {
if (field.IsStatic) {
return corClass.GetStaticFieldValue(field.Token, curFrame);
if (method.IsStatic) {
return new ICorDebugValue[] {};
} else {
if (this.SoftReference != null) {
return new ICorDebugValue[] {this.SoftReference.CastTo<ICorDebugValue>()};
} else {
return (val.CorValue.CastTo<ICorDebugObjectValue>()).GetFieldValue(corClass, field.Token);
return new ICorDebugValue[] {this.CorValue};
}
} catch {
throw new CannotGetValueException();
}
}
public Variable GetBaseClassVariable(PersistentValue pValue)
public Variable GetBaseClassVariable()
{
if (HasBaseClass) {
return new Variable(debugger,
"<Base class>",
new PersistentValue(delegate { return GetBaseClassValue(pValue); }));
new PersistentValue(debugger, delegate { return GetBaseClassValue(); }));
} else {
return null;
}
}
Value GetBaseClassValue(PersistentValue pValue)
Value GetBaseClassValue()
{
Value updatedVal = pValue.Value;
if (updatedVal is UnavailableValue) return updatedVal;
if (this.IsEquivalentValue(updatedVal)) {
return ((ObjectValue)updatedVal).BaseClass;
} else {
return new UnavailableValue(debugger, "Object type changed");
}
if (!IsCorValueCompatible) return new UnavailableValue(debugger, "Object type changed");
return this.BaseClass;
}
public unsafe ObjectValue BaseClass {
get {
if (baseClass == null) baseClass = GetBaseClass();
if (baseClass == null) throw new DebuggerException("Object doesn't have a base class. You may use HasBaseClass to check this.");
return baseClass;
}
}
public bool HasBaseClass {
get {
if (baseClass == null) {
try {
baseClass = GetBaseClass();
} catch (DebuggerException) {
baseClass = null;
}
}
return (baseClass != null);
}
}
protected ObjectValue GetBaseClass()
protected static ICorDebugClass GetSuperClass(NDebugger debugger, ICorDebugClass currClass)
{
string fullTypeName = "<>";
// If referencing to external assembly
if ((classProps.SuperClassToken & 0x01000000) != 0) {
fullTypeName = metaData.GetTypeRefProps(classProps.SuperClassToken).Name;
classProps.SuperClassToken = 0;
foreach (Module m in debugger.Modules)
{
Module currModule = debugger.GetModule(currClass.Module);
uint superToken = currModule.MetaData.GetTypeDefProps(currClass.Token).SuperClassToken;
// It has no base class
if ((superToken & 0x00FFFFFF) == 0x00000000) return null;
// TypeDef - Localy defined
if ((superToken & 0xFF000000) == 0x02000000) {
return currModule.CorModule.GetClassFromToken(superToken);
}
// TypeRef - Referencing to external assembly
if ((superToken & 0xFF000000) == 0x01000000) {
string fullTypeName = currModule.MetaData.GetTypeRefProps(superToken).Name;
foreach (Module superModule in debugger.Modules) {
// TODO: Does not work for nested
// see FindTypeDefByName in dshell.cpp
// TODO: preservesig
try {
classProps.SuperClassToken = m.MetaData.FindTypeDefByName(fullTypeName, 0).Token;
uint token = superModule.MetaData.FindTypeDefByName(fullTypeName, 0).Token;
return superModule.CorModule.GetClassFromToken(token);
} catch {
continue;
}
corModuleSuperclass = m.CorModule;
break;
}
}
// If it has no base class
if ((classProps.SuperClassToken & 0x00FFFFFF) == 0) {
throw new DebuggerException("Unable to get base class: " + fullTypeName);
} else {
ICorDebugClass superClass = corModuleSuperclass.GetClassFromToken(classProps.SuperClassToken);
if (corHandleValue != null) {
return new ObjectValue(debugger, new PersistentValue(debugger, corHandleValue.As<ICorDebugValue>()), superClass);
} else {
return new ObjectValue(debugger, new PersistentValue(debugger, CorValue), superClass);
throw new DebuggerException("Superclass not found");
}
/*
// May return null
public Eval ToStringEval {
get {
ObjectValue baseClassObject = this.BaseClassObject;
foreach(MethodProps method in baseClassObject.Methods) {
if (method.Name == "ToString") {
ICorDebugValue[] evalArgs;
ICorDebugFunction evalCorFunction;
baseClassObject.Module.CorModule.GetFunctionFromToken(method.Token, out evalCorFunction);
evalArgs = new ICorDebugValue[] {this.SoftReference};
return new Eval(debugger, evalCorFunction, evalArgs);
}
}
throw new DebuggerException("ToString method not found");
}
}
*/
}
}

54
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PersistentValue.cs

@ -33,8 +33,6 @@ namespace Debugger @@ -33,8 +33,6 @@ namespace Debugger
ValueGetter valueGetter;
IsExpiredDelegate isExpired;
public ICorDebugValue initValue;
public NDebugger Debugger {
get {
return debugger;
@ -42,6 +40,12 @@ namespace Debugger @@ -42,6 +40,12 @@ namespace Debugger
}
public ICorDebugValue CorValue {
get {
return PersistentValue.DereferenceUnbox(RawCorValue);
}
}
ICorDebugValue RawCorValue {
get {
return corValueGetter();
}
@ -67,46 +71,53 @@ namespace Debugger @@ -67,46 +71,53 @@ namespace Debugger
get {
if (this.IsExpired) throw new DebuggerException("CorValue has expired");
if (this.initValue != null && this.initValue.Is<ICorDebugHandleValue>()) {
return this.initValue.As<ICorDebugHandleValue>();
} else if (this.initValue != null && this.initValue.Is<ICorDebugHeapValue2>()) {
return this.initValue.As<ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION);
ICorDebugValue corValue = RawCorValue;
if (corValue != null && corValue.Is<ICorDebugHandleValue>()) {
return corValue.As<ICorDebugHandleValue>();
}
corValue = PersistentValue.DereferenceUnbox(corValue);
if (corValue != null && corValue.Is<ICorDebugHeapValue2>()) {
return corValue.As<ICorDebugHeapValue2>().CreateHandle(CorDebugHandleType.HANDLE_WEAK_TRACK_RESURRECTION);
} else {
return null; // Value type
}
}
}
public PersistentValue(ValueGetter getter)
public PersistentValue(NDebugger debugger, ValueGetter valueGetter)
{
this.valueGetter = getter;
this.debugger = debugger;
this.corValueGetter = delegate { throw new CannotGetValueException("CorValue not available for custom value"); };
this.isExpired = delegate { return false; };
this.valueGetter = valueGetter;
}
public PersistentValue(NDebugger debugger, ICorDebugValue corValue)
{
this.debugger = debugger;
this.initValue = corValue;
PauseSession pauseSessionAtCreation = debugger.PauseSession;
DebugeeState debugeeStateAtCreation = debugger.DebugeeState;
this.debugger = debugger;
this.corValueGetter = delegate {
if (this.IsExpired) throw new DebuggerException("CorValue has expired");
return PersistentValue.DereferenceUnbox(this.initValue);
if (this.IsExpired) throw new CannotGetValueException("CorValue has expired");
return corValue;
};
this.isExpired = delegate {
if (this.initValue != null && this.initValue.Is<ICorDebugHandleValue>()) {
if (corValue != null && corValue.Is<ICorDebugHandleValue>()) {
return debugeeStateAtCreation != debugger.DebugeeState;
} else {
return pauseSessionAtCreation != debugger.PauseSession;
}
};
this.valueGetter = delegate { return CreateValue(debugger, corValue); };
this.valueGetter = delegate { return CreateValue(); };
}
public PersistentValue(NDebugger debugger, CorValueGetter corValueGetter)
{
this.valueGetter = delegate { return CreateValue(debugger, corValueGetter()); };
this.debugger = debugger;
this.corValueGetter = corValueGetter;
this.isExpired = delegate { return false; };
this.valueGetter = delegate { return CreateValue(); };
}
internal static ICorDebugValue DereferenceUnbox(ICorDebugValue corValue)
@ -134,11 +145,12 @@ namespace Debugger @@ -134,11 +145,12 @@ namespace Debugger
return corValue;
}
static Value CreateValue(NDebugger debugger, ICorDebugValue corValue)
Value CreateValue()
{
ICorDebugValue corValue = RawCorValue;
ICorDebugValue derefed = DereferenceUnbox(corValue);
if (derefed == null) {
return new NullValue(debugger, new PersistentValue(debugger, corValue));
return new NullValue(debugger, this);
}
CorElementType type = Value.GetCorType(derefed);
@ -160,16 +172,16 @@ namespace Debugger @@ -160,16 +172,16 @@ namespace Debugger
case CorElementType.I:
case CorElementType.U:
case CorElementType.STRING:
return new PrimitiveValue(debugger, new PersistentValue(debugger, corValue));
return new PrimitiveValue(debugger, this);
case CorElementType.ARRAY:
case CorElementType.SZARRAY: // Short-cut for single dimension zero lower bound array
return new ArrayValue(debugger, new PersistentValue(debugger, corValue));
return new ArrayValue(debugger, this);
case CorElementType.VALUETYPE:
case CorElementType.CLASS:
case CorElementType.OBJECT: // Short-cut for Class "System.Object"
return new ObjectValue(debugger, new PersistentValue(debugger, corValue));
return new ObjectValue(debugger, this);
default: // Unknown type
return new UnavailableValue(debugger, "Unknown value type");

6
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/PropertyVariable.cs

@ -24,7 +24,7 @@ namespace Debugger @@ -24,7 +24,7 @@ namespace Debugger
internal PropertyVariable(NDebugger debugger, string name, bool isStatic, bool isPublic, EvalCreator evalCreator):base(debugger, name, isStatic, isPublic, null)
{
this.evalCreator = evalCreator;
this.pValue = new PersistentValue(delegate { return GetValueOfResult(); });
this.pValue = new PersistentValue(debugger, delegate { return GetValueOfResult(); });
}
Value GetValueOfResult()
@ -51,8 +51,8 @@ namespace Debugger @@ -51,8 +51,8 @@ namespace Debugger
if (cachedEval == null || cachedEval.HasExpired) {
cachedEval = evalCreator();
if (cachedEval != null) {
cachedEval.EvalStarted += delegate { OnValueChanged(); };
cachedEval.EvalComplete += delegate { OnValueChanged(); };
cachedEval.EvalStarted += delegate { OnValueChanged(this, null); };
cachedEval.EvalComplete += delegate { OnValueChanged(this, null); };
}
}
return cachedEval;

29
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Value.cs

@ -16,7 +16,7 @@ namespace Debugger @@ -16,7 +16,7 @@ namespace Debugger
public abstract class Value: RemotingObjectBase
{
protected NDebugger debugger;
PersistentValue pValue;
protected PersistentValue pValue;
public event EventHandler<ValueEventArgs> ValueChanged;
@ -26,12 +26,6 @@ namespace Debugger @@ -26,12 +26,6 @@ namespace Debugger
}
}
protected ICorDebugHandleValue corHandleValue {
get {
return pValue.initValue.As<ICorDebugHandleValue>();
}
}
internal ICorDebugValue CorValue {
get {
return pValue.CorValue;
@ -44,6 +38,12 @@ namespace Debugger @@ -44,6 +38,12 @@ namespace Debugger
}
}
protected Value FreshValue {
get {
return pValue.Value;
}
}
/// <summary>
/// If true than the value is no longer valid and you should obtain updated copy
/// </summary>
@ -88,23 +88,14 @@ namespace Debugger @@ -88,23 +88,14 @@ namespace Debugger
/// <summary>
/// Gets the subvariables of this value
/// </summary>
/// <param name="getter">Delegate that will be called to get the up-to-date value</param>
public virtual IEnumerable<Variable> GetSubVariables(PersistentValue pValue)
public virtual IEnumerable<Variable> GetSubVariables()
{
yield break;
}
/// <summary>
/// Gets whether the given value is equivalent to this one. (ie it is may be just its other instance)
/// </summary>
public virtual bool IsEquivalentValue(Value val)
{
return val.GetType() == this.GetType();
}
public Variable this[string variableName] {
get {
foreach(Variable v in GetSubVariables(new PersistentValue(delegate{ return this.IsExpired?new UnavailableValue(debugger, "Value has expired"):this;}))) {
foreach(Variable v in GetSubVariables()) {
if (v.Name == variableName) return v;
}
throw new DebuggerException("Subvariable " + variableName + " does not exist");
@ -157,7 +148,7 @@ namespace Debugger @@ -157,7 +148,7 @@ namespace Debugger
}
/// <summary>
/// Returns true if the value is signed or unsigned integer of any siz
/// Returns true if the value is signed or unsigned integer of any size
/// </summary>
public bool IsInteger {
get {

29
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Variable.cs

@ -19,7 +19,6 @@ namespace Debugger @@ -19,7 +19,6 @@ namespace Debugger
VariableCollection subVariables;
internal protected PersistentValue pValue;
internal Value cachedValue;
event EventHandler<DebuggerEventArgs> valueChanged;
public event EventHandler<VariableCollectionEventArgs> ValueRemovedFromCollection;
@ -55,15 +54,10 @@ namespace Debugger @@ -55,15 +54,10 @@ namespace Debugger
/// </summary>
public Value Value {
get {
if (cachedValue == null || cachedValue.IsExpired) {
cachedValue = pValue.Value;
if (cachedValue == null) throw new DebuggerException("ValueGetter returned null");
cachedValue.ValueChanged += delegate { OnValueChanged(); };
}
if (cachedValue.IsExpired) {
return new UnavailableValue(debugger, "The value has expired");
}
return cachedValue;
Value val = pValue.Value;
val.ValueChanged -= OnValueChanged;
val.ValueChanged += OnValueChanged;
return val;
}
}
@ -84,9 +78,8 @@ namespace Debugger @@ -84,9 +78,8 @@ namespace Debugger
}
}
protected internal virtual void OnValueChanged()
protected internal virtual void OnValueChanged(object sender, ValueEventArgs e)
{
cachedValue = null;
if (valueChanged != null) {
valueChanged(this, new VariableEventArgs(this));
}
@ -98,16 +91,6 @@ namespace Debugger @@ -98,16 +91,6 @@ namespace Debugger
}
}
public Variable(NDebugger debugger, ICorDebugValue corValue, string name):this(new PersistentValue(debugger, corValue).Value, name)
{
}
public Variable(Value val, string name):this(val.Debugger, name, new PersistentValue(delegate {return val;}))
{
}
public Variable(NDebugger debugger, string name, PersistentValue pValue)
{
this.debugger = debugger;
@ -126,7 +109,7 @@ namespace Debugger @@ -126,7 +109,7 @@ namespace Debugger
void OnSubVariablesUpdating(object sender, VariableCollectionEventArgs e)
{
subVariables.UpdateTo(Value.GetSubVariables(new PersistentValue(delegate{return this.Value;})));
subVariables.UpdateTo(Value.GetSubVariables());
}
}
}

3
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/VariableCollection.cs

@ -149,13 +149,12 @@ namespace Debugger @@ -149,13 +149,12 @@ namespace Debugger
// Trasfer the new variable into the old one
if (oldVariable != newVariable) {
oldVariable.pValue = newVariable.pValue;
oldVariable.cachedValue = null;
if (newVariable is ClassVariable && oldVariable is ClassVariable) {
((ClassVariable)oldVariable).isPublic = ((ClassVariable)oldVariable).isPublic;
((ClassVariable)oldVariable).isStatic = ((ClassVariable)oldVariable).isStatic;
}
if (newVariable is PropertyVariable) {
newVariable.ValueChanged += delegate { oldVariable.OnValueChanged(); };
newVariable.ValueChanged += delegate { oldVariable.OnValueChanged(this, null); };
}
}
// Keep the variable in the list

Loading…
Cancel
Save