Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/Core/Echo/Memory/BasicMemorySpace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ namespace Echo.Memory
/// </summary>
public class BasicMemorySpace : IMemorySpace
{
private long _baseAddress;
private AddressRange _addressRange;

/// <summary>
/// Creates a new memory space.
/// </summary>
Expand All @@ -19,23 +19,25 @@ public BasicMemorySpace(int size, bool initialize)
: this(new BitVector(size * 8, initialize))
{
}

/// <summary>
/// Wraps a byte array into a memory space.
/// </summary>
/// <param name="backBuffer">The data of the memory space.</param>
public BasicMemorySpace(byte[] backBuffer)
{
BackBuffer = new BitVector(backBuffer);
_addressRange = new AddressRange(0, BackBuffer.Count / 8);
}

/// <summary>
/// Wraps a bit vector into a memory space.
/// </summary>
/// <param name="backBuffer">The data of the memory space.</param>
public BasicMemorySpace(BitVector backBuffer)
{
BackBuffer = backBuffer;
_addressRange = new AddressRange(0, BackBuffer.Count / 8);
}

/// <summary>
Expand All @@ -47,30 +49,33 @@ public BitVector BackBuffer
}

/// <inheritdoc />
public AddressRange AddressRange => new(_baseAddress, _baseAddress + BackBuffer.Count / 8);
public AddressRange AddressRange => _addressRange;

/// <inheritdoc />
public bool IsValidAddress(long address) => AddressRange.Contains(address);
public bool IsValidAddress(long address) => _addressRange.Contains(address);

/// <inheritdoc />
public void Rebase(long baseAddress) => _baseAddress = baseAddress;
public void Rebase(long baseAddress)
{
_addressRange = new AddressRange(baseAddress, baseAddress + BackBuffer.Count / 8);
}

/// <inheritdoc />
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);
}

/// <inheritdoc />
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));
}

/// <inheritdoc />
public void Write(long address, ReadOnlySpan<byte> buffer)
{
BackBuffer.AsSpan((int) ((address - _baseAddress) * 8)).Write(buffer);
BackBuffer.AsSpan((int) ((address - _addressRange.Start) * 8)).Write(buffer);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class HostObject : IMemorySpace
private readonly Dictionary<uint, FieldInfo> _fields = new();
private readonly CilVirtualMachine _machine;
private readonly TypeMemoryLayout _virtualLayout;
private long _baseAddress;
private AddressRange _addressRange;

/// <summary>
/// Creates a new managed object embedding.
Expand All @@ -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);
}

/// <summary>
Expand All @@ -44,21 +45,24 @@ public object Object
/// </summary>

/// <inheritdoc />
public AddressRange AddressRange => new(_baseAddress, _baseAddress + _machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
public AddressRange AddressRange => _addressRange;

/// <inheritdoc />
public bool IsValidAddress(long address) => AddressRange.Contains(address);
public bool IsValidAddress(long address) => _addressRange.Contains(address);

/// <inheritdoc />
public void Rebase(long baseAddress) => _baseAddress = baseAddress;
public void Rebase(long baseAddress)
{
_addressRange = new AddressRange(baseAddress, baseAddress + _machine.ValueFactory.ObjectHeaderSize + _virtualLayout.Size);
}

/// <inheritdoc />
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);
Expand Down Expand Up @@ -108,7 +112,7 @@ private void ReadFromObject(uint offset, BitVectorSpan buffer)
/// <inheritdoc />
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public partial class CallFrame : IMemorySpace
private readonly List<uint> _offsets = new();
private readonly List<ExceptionHandlerFrame> _exceptionHandlers = new();
private BitVector _localStorage;
private long _baseAddress;
private AddressRange _addressRange;

/// <summary>
/// Constructs a new call stack frame.
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -172,10 +173,10 @@ void AllocateFrameField(TypeSignature type)
public ITypeDescriptor? ConstrainedType { get; set; }

/// <inheritdoc />
public AddressRange AddressRange => new(_baseAddress, _baseAddress + _localStorage.ByteCount);
public AddressRange AddressRange => _addressRange;

/// <inheritdoc />
public bool IsValidAddress(long address) => AddressRange.Contains(address);
public bool IsValidAddress(long address) => _addressRange.Contains(address);

/// <summary>
/// Allocates local stack memory in the stack frame.
Expand All @@ -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;
}

/// <inheritdoc />
public void Rebase(long baseAddress) => _baseAddress = baseAddress;
public void Rebase(long baseAddress)
{
_addressRange = new AddressRange(baseAddress, baseAddress + _localStorage.ByteCount);
}

/// <summary>
/// Gets the address (relative to the start of the frame) to a local variable in the frame.
Expand All @@ -208,7 +213,7 @@ public long Allocate(int size)
/// <returns>The address</returns>
/// <exception cref="ArgumentOutOfRangeException">Occurs when the local index is invalid.</exception>
public long GetLocalAddress(int index) => index < LocalsCount
? _baseAddress + _offsets[index]
? _addressRange.Start + _offsets[index]
: throw new ArgumentOutOfRangeException(nameof(index));

/// <summary>
Expand Down Expand Up @@ -251,7 +256,7 @@ public BitVector ReadLocal(int index)
/// <returns>The address</returns>
/// <exception cref="ArgumentOutOfRangeException">Occurs when the argument index is invalid.</exception>
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));

/// <summary>
Expand Down Expand Up @@ -290,19 +295,19 @@ public BitVector ReadArgument(int index)
/// <inheritdoc />
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);
}

/// <inheritdoc />
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));
}

/// <inheritdoc />
public void Write(long address, ReadOnlySpan<byte> 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()
Expand Down
Loading