diff --git a/src/Core/Echo/Memory/BasicMemorySpace.cs b/src/Core/Echo/Memory/BasicMemorySpace.cs
index a0713e0e..ca49413a 100644
--- a/src/Core/Echo/Memory/BasicMemorySpace.cs
+++ b/src/Core/Echo/Memory/BasicMemorySpace.cs
@@ -8,8 +8,8 @@ namespace Echo.Memory
///
public class BasicMemorySpace : IMemorySpace
{
- private long _baseAddress;
-
+ private AddressRange _addressRange;
+
///
/// Creates a new memory space.
///
@@ -19,7 +19,7 @@ public BasicMemorySpace(int size, bool initialize)
: this(new BitVector(size * 8, initialize))
{
}
-
+
///
/// Wraps a byte array into a memory space.
///
@@ -27,8 +27,9 @@ public BasicMemorySpace(int size, bool initialize)
public BasicMemorySpace(byte[] backBuffer)
{
BackBuffer = new BitVector(backBuffer);
+ _addressRange = new AddressRange(0, BackBuffer.Count / 8);
}
-
+
///
/// Wraps a bit vector into a memory space.
///
@@ -36,6 +37,7 @@ public BasicMemorySpace(byte[] backBuffer)
public BasicMemorySpace(BitVector backBuffer)
{
BackBuffer = backBuffer;
+ _addressRange = new AddressRange(0, BackBuffer.Count / 8);
}
///
@@ -47,30 +49,33 @@ public BitVector BackBuffer
}
///
- public AddressRange AddressRange => new(_baseAddress, _baseAddress + BackBuffer.Count / 8);
+ public AddressRange AddressRange => _addressRange;
///
- public bool IsValidAddress(long address) => AddressRange.Contains(address);
+ public bool IsValidAddress(long address) => _addressRange.Contains(address);
///
- public void Rebase(long baseAddress) => _baseAddress = baseAddress;
+ public void Rebase(long baseAddress)
+ {
+ _addressRange = new AddressRange(baseAddress, baseAddress + BackBuffer.Count / 8);
+ }
///
public void Read(long address, BitVectorSpan buffer)
{
- BackBuffer.AsSpan((int) (address - _baseAddress) * 8, buffer.Count).CopyTo(buffer);
+ BackBuffer.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count).CopyTo(buffer);
}
///
public void Write(long address, BitVectorSpan buffer)
{
- buffer.CopyTo(BackBuffer.AsSpan((int) (address - _baseAddress) * 8, buffer.Count));
+ buffer.CopyTo(BackBuffer.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count));
}
///
public void Write(long address, ReadOnlySpan buffer)
{
- BackBuffer.AsSpan((int) ((address - _baseAddress) * 8)).Write(buffer);
+ BackBuffer.AsSpan((int) ((address - _addressRange.Start) * 8)).Write(buffer);
}
}
}
\ No newline at end of file
diff --git a/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Heap/HostObject.cs b/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Heap/HostObject.cs
index 91fb4962..b3e581d4 100644
--- a/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Heap/HostObject.cs
+++ b/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Heap/HostObject.cs
@@ -17,7 +17,7 @@ public class HostObject : IMemorySpace
private readonly Dictionary _fields = new();
private readonly CilVirtualMachine _machine;
private readonly TypeMemoryLayout _virtualLayout;
- private long _baseAddress;
+ private AddressRange _addressRange;
///
/// Creates a new managed object embedding.
@@ -29,6 +29,7 @@ public HostObject(object o, CilVirtualMachine machine)
Object = o ?? throw new ArgumentNullException(nameof(o));
_virtualLayout = GetLayout(machine.ValueFactory, o);
_machine = machine;
+ _addressRange = new AddressRange(0, machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
}
///
@@ -44,13 +45,16 @@ public object Object
///
///
- public AddressRange AddressRange => new(_baseAddress, _baseAddress + _machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
+ public AddressRange AddressRange => _addressRange;
///
- public bool IsValidAddress(long address) => AddressRange.Contains(address);
+ public bool IsValidAddress(long address) => _addressRange.Contains(address);
///
- public void Rebase(long baseAddress) => _baseAddress = baseAddress;
+ public void Rebase(long baseAddress)
+ {
+ _addressRange = new AddressRange(baseAddress, baseAddress + _machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
+ }
///
public void Read(long address, BitVectorSpan buffer)
@@ -58,7 +62,7 @@ public void Read(long address, BitVectorSpan buffer)
buffer.MarkFullyUnknown();
// First field in an object is always its method table (i.e., pointer to its type).
- uint offset = (uint) (address - _baseAddress);
+ uint offset = (uint) (address - _addressRange.Start);
if (offset == 0)
{
long methodTable = _machine.ValueFactory.ClrMockMemory.MethodTables.GetAddress(_virtualLayout.Type);
@@ -108,7 +112,7 @@ private void ReadFromObject(uint offset, BitVectorSpan buffer)
///
public void Write(long address, BitVectorSpan buffer)
{
- uint offset = (uint) (address - _baseAddress);
+ uint offset = (uint) (address - _addressRange.Start);
if (Object.GetType().IsArray)
WriteToArray(offset, buffer);
diff --git a/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Stack/CallFrame.cs b/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Stack/CallFrame.cs
index d51642cb..95d69c7e 100644
--- a/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Stack/CallFrame.cs
+++ b/src/Platforms/Echo.Platforms.AsmResolver/Emulation/Stack/CallFrame.cs
@@ -30,7 +30,7 @@ public partial class CallFrame : IMemorySpace
private readonly List _offsets = new();
private readonly List _exceptionHandlers = new();
private BitVector _localStorage;
- private long _baseAddress;
+ private AddressRange _addressRange;
///
/// Constructs a new call stack frame.
@@ -89,7 +89,8 @@ internal CallFrame(IMethodDescriptor method, ValueFactory factory, bool isRoot)
// Actually reserve space for the entire frame.
_localStorage = new BitVector((int) (currentOffset * 8), false);
-
+ _addressRange = new AddressRange(0, _localStorage.ByteCount);
+
// Initialize locals to zero when method body says we should.
if (_initializeLocals)
{
@@ -172,10 +173,10 @@ void AllocateFrameField(TypeSignature type)
public ITypeDescriptor? ConstrainedType { get; set; }
///
- public AddressRange AddressRange => new(_baseAddress, _baseAddress + _localStorage.ByteCount);
+ public AddressRange AddressRange => _addressRange;
///
- public bool IsValidAddress(long address) => AddressRange.Contains(address);
+ public bool IsValidAddress(long address) => _addressRange.Contains(address);
///
/// Allocates local stack memory in the stack frame.
@@ -189,17 +190,21 @@ public long Allocate(int size)
if (size < 0)
throw new ArgumentOutOfRangeException(nameof(size));
- long address = AddressRange.End;
+ long address = _addressRange.End;
int originalSize = _localStorage.Count;
_localStorage = _localStorage.Resize(originalSize + size * 8, false);
if (!_initializeLocals)
_localStorage.AsSpan(originalSize, _localStorage.Count - originalSize).MarkFullyUnknown();
-
+
+ _addressRange = new AddressRange(_addressRange.Start, _addressRange.Start + _localStorage.ByteCount);
return address;
}
///
- public void Rebase(long baseAddress) => _baseAddress = baseAddress;
+ public void Rebase(long baseAddress)
+ {
+ _addressRange = new AddressRange(baseAddress, baseAddress + _localStorage.ByteCount);
+ }
///
/// Gets the address (relative to the start of the frame) to a local variable in the frame.
@@ -208,7 +213,7 @@ public long Allocate(int size)
/// The address
/// Occurs when the local index is invalid.
public long GetLocalAddress(int index) => index < LocalsCount
- ? _baseAddress + _offsets[index]
+ ? _addressRange.Start + _offsets[index]
: throw new ArgumentOutOfRangeException(nameof(index));
///
@@ -251,7 +256,7 @@ public BitVector ReadLocal(int index)
/// The address
/// Occurs when the argument index is invalid.
public long GetArgumentAddress(int index) => index < Method.Signature!.GetTotalParameterCount()
- ? _baseAddress + _offsets[LocalsCount + 1 + index]
+ ? _addressRange.Start + _offsets[LocalsCount + 1 + index]
: throw new ArgumentOutOfRangeException(nameof(index));
///
@@ -290,19 +295,19 @@ public BitVector ReadArgument(int index)
///
public void Read(long address, BitVectorSpan buffer)
{
- _localStorage.AsSpan((int) (address - _baseAddress) * 8, buffer.Count).CopyTo(buffer);
+ _localStorage.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count).CopyTo(buffer);
}
///
public void Write(long address, BitVectorSpan buffer)
{
- buffer.CopyTo(_localStorage.AsSpan((int) (address - _baseAddress) * 8, buffer.Count));
+ buffer.CopyTo(_localStorage.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Count));
}
///
public void Write(long address, ReadOnlySpan buffer)
{
- _localStorage.AsSpan((int) (address - _baseAddress) * 8, buffer.Length).Write(buffer);
+ _localStorage.AsSpan((int) (address - _addressRange.Start) * 8, buffer.Length).Write(buffer);
}
private void InitializeExceptionHandlerFrames()