1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
using System;
namespace Mono.Debugger.Languages.Mono
{
internal class MonoArrayObject : TargetArrayObject
{
public MonoArrayObject (MonoArrayType type, TargetLocation location)
: base (type, location)
{ }
protected override void DoGetArrayBounds (TargetMemoryAccess target)
{
TargetBinaryReader reader = Location.ReadMemory (target, type.Size).GetReader ();
reader.Position = 3 * reader.TargetMemoryInfo.TargetAddressSize;
int length = reader.ReadInt32 ();
if (Rank == 1) {
bounds = new ArrayBounds [1];
bounds [0] = new ArrayBounds (0, length);
return;
}
reader.Position = 2 * reader.TargetMemoryInfo.TargetAddressSize;
TargetAddress bounds_address = new TargetAddress (
target.AddressDomain, reader.ReadAddress ());
TargetBinaryReader breader = target.ReadMemory (
bounds_address, 8 * Rank).GetReader ();
bounds = new ArrayBounds [Rank];
for (int i = 0; i < Rank; i++) {
int b_length = breader.ReadInt32 ();
int b_lower = breader.ReadInt32 ();
bounds [i] = new ArrayBounds (b_lower, b_length);
}
}
internal override TargetObject GetElement (TargetMemoryAccess target, int[] indices)
{
int offset = GetArrayOffset (target, indices);
TargetBlob blob;
TargetLocation dynamic_location;
try {
blob = Location.ReadMemory (target, Type.Size);
GetDynamicSize (target, blob, Location, out dynamic_location);
} catch (TargetException ex) {
throw new LocationInvalidException (ex);
}
TargetLocation new_loc = dynamic_location.GetLocationAtOffset (offset);
if (Type.ElementType.IsByRef)
new_loc = new_loc.GetDereferencedLocation ();
if (new_loc.HasAddress && new_loc.GetAddress (target).IsNull)
return new MonoNullObject (Type.ElementType, new_loc);
return Type.ElementType.GetObject (target, new_loc);
}
internal override void SetElement (TargetMemoryAccess target, int[] indices,
TargetObject obj)
{
int offset = GetArrayOffset (target, indices);
TargetBlob blob;
TargetLocation dynamic_location;
try {
blob = Location.ReadMemory (target, Type.Size);
GetDynamicSize (target, blob, Location, out dynamic_location);
} catch (TargetException ex) {
throw new LocationInvalidException (ex);
}
TargetLocation new_loc = dynamic_location.GetLocationAtOffset (offset);
Type.ElementType.SetObject (target, new_loc, obj);
}
int GetElementSize (TargetInfo info)
{
if (Type.ElementType.IsByRef)
return info.TargetAddressSize;
else if (Type.ElementType.HasFixedSize)
return Type.ElementType.Size;
else
throw new InvalidOperationException ();
}
internal override long GetDynamicSize (TargetMemoryAccess target, TargetBlob blob,
TargetLocation location,
out TargetLocation dynamic_location)
{
int element_size = GetElementSize (blob.TargetMemoryInfo);
dynamic_location = location.GetLocationAtOffset (Type.Size);
return element_size * GetLength (target);
}
internal override string Print (TargetMemoryAccess target)
{
if (Location.HasAddress)
return String.Format ("{0}", Location.GetAddress (target));
else
return String.Format ("{0}", Location);
}
public override bool HasClassObject {
get { return true; }
}
internal override TargetClassObject GetClassObject (TargetMemoryAccess target)
{
return (TargetClassObject) Type.Language.ArrayType.GetObject (target, Location);
}
}
}
|