Skip to content

Commit d79cd32

Browse files
authored
[cdac] Pass a delegate into Target (#105043)
1 parent a5c0dec commit d79cd32

File tree

3 files changed

+20
-28
lines changed

3 files changed

+20
-28
lines changed

src/native/managed/cdacreader/src/Entrypoints.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ internal static class Entrypoints
1515
private static unsafe int Init(ulong descriptor, delegate* unmanaged<ulong, byte*, uint, void*, int> readFromTarget, void* readContext, IntPtr* handle)
1616
{
1717
// TODO: [cdac] Better error code/details
18-
if (!Target.TryCreate(descriptor, readFromTarget, readContext, out Target? target))
18+
if (!Target.TryCreate(descriptor, (address, buffer) =>
19+
{
20+
fixed (byte* bufferPtr = buffer)
21+
{
22+
return readFromTarget(address, bufferPtr, (uint)buffer.Length, readContext);
23+
}
24+
}, out Target? target))
1925
return -1;
2026

2127
GCHandle gcHandle = GCHandle.Alloc(target);

src/native/managed/cdacreader/src/Target.cs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,11 @@ private readonly struct Configuration
9494
internal DataCache ProcessedData { get; }
9595
internal Helpers.Metadata Metadata { get; }
9696

97-
public static bool TryCreate(ulong contractDescriptor, delegate* unmanaged<ulong, byte*, uint, void*, int> readFromTarget, void* readContext, out Target? target)
97+
public delegate int ReadFromTargetDelegate(ulong address, Span<byte> bufferToFill);
98+
99+
public static bool TryCreate(ulong contractDescriptor, ReadFromTargetDelegate readFromTarget, out Target? target)
98100
{
99-
Reader reader = new Reader(readFromTarget, readContext);
101+
Reader reader = new Reader(readFromTarget);
100102
if (TryReadContractDescriptor(contractDescriptor, reader, out Configuration config, out ContractDescriptorParser.ContractDescriptor? descriptor, out TargetPointer[] pointerData))
101103
{
102104
target = new Target(config, descriptor!, pointerData, reader);
@@ -458,26 +460,14 @@ public bool TryGet<T>(ulong address, [NotNullWhen(true)] out T? data)
458460
}
459461
}
460462

461-
private sealed class Reader
463+
private readonly struct Reader(ReadFromTargetDelegate readFromTarget)
462464
{
463-
private readonly delegate* unmanaged<ulong, byte*, uint, void*, int> _readFromTarget;
464-
private readonly void* _context;
465-
466-
public Reader(delegate* unmanaged<ulong, byte*, uint, void*, int> readFromTarget, void* context)
467-
{
468-
_readFromTarget = readFromTarget;
469-
_context = context;
470-
}
471-
472465
public int ReadFromTarget(ulong address, Span<byte> buffer)
473466
{
474-
fixed (byte* bufferPtr = buffer)
475-
{
476-
return _readFromTarget(address, bufferPtr, (uint)buffer.Length, _context);
477-
}
467+
return readFromTarget(address, buffer);
478468
}
479469

480470
public int ReadFromTarget(ulong address, byte* buffer, uint bytesToRead)
481-
=> _readFromTarget(address, buffer, bytesToRead, _context);
471+
=> readFromTarget(address, new Span<byte>(buffer, checked((int)bytesToRead)));
482472
}
483473
}

src/native/managed/cdacreader/tests/MockMemorySpace.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,20 +159,16 @@ public static ReadContext CreateContext(ReadOnlySpan<byte> descriptor, ReadOnlyS
159159

160160
public static bool TryCreateTarget(ReadContext* context, out Target? target)
161161
{
162-
return Target.TryCreate(ContractDescriptorAddr, &ReadFromTarget, context, out target);
162+
return Target.TryCreate(ContractDescriptorAddr, (address, buffer) => ReadFromTarget(address, buffer, context), out target);
163163
}
164164

165-
[UnmanagedCallersOnly]
166-
private static int ReadFromTarget(ulong address, byte* buffer, uint length, void* context)
165+
private static int ReadFromTarget(ulong address, Span<byte> span, ReadContext* readContext)
167166
{
168-
ReadContext* readContext = (ReadContext*)context;
169-
var span = new Span<byte>(buffer, (int)length);
170-
171167
// Populate the span with the requested portion of the contract descriptor
172-
if (address >= ContractDescriptorAddr && address <= ContractDescriptorAddr + (ulong)readContext->ContractDescriptorLength - length)
168+
if (address >= ContractDescriptorAddr && address <= ContractDescriptorAddr + (ulong)readContext->ContractDescriptorLength - (uint)span.Length)
173169
{
174170
ulong offset = address - ContractDescriptorAddr;
175-
new ReadOnlySpan<byte>(readContext->ContractDescriptor + offset, (int)length).CopyTo(span);
171+
new ReadOnlySpan<byte>(readContext->ContractDescriptor + offset, span.Length).CopyTo(span);
176172
return 0;
177173
}
178174

@@ -184,10 +180,10 @@ private static int ReadFromTarget(ulong address, byte* buffer, uint length, void
184180
}
185181

186182
// Populate the span with the requested portion of the pointer data
187-
if (address >= ContractPointerDataAddr && address <= ContractPointerDataAddr + (ulong)readContext->PointerDataLength - length)
183+
if (address >= ContractPointerDataAddr && address <= ContractPointerDataAddr + (ulong)readContext->PointerDataLength - (uint)span.Length)
188184
{
189185
ulong offset = address - ContractPointerDataAddr;
190-
new ReadOnlySpan<byte>(readContext->PointerData + offset, (int)length).CopyTo(span);
186+
new ReadOnlySpan<byte>(readContext->PointerData + offset, span.Length).CopyTo(span);
191187
return 0;
192188
}
193189

0 commit comments

Comments
 (0)