Skip to content

Commit a7403ba

Browse files
committed
Add CopyTo() to ReadOnlySpan<T>
- Add implementation for this method. - Update declaration of mscorlib.
1 parent 1ae4494 commit a7403ba

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

src/CLR/CorLib/corlib_native.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,7 @@ static const CLR_RT_MethodHandler method_lookup[] =
702702
nullptr,
703703
nullptr,
704704
nullptr,
705+
Library_corlib_native_System_ReadOnlySpan_1::CopyTo___VOID__SystemSpan_1,
705706
nullptr,
706707
nullptr,
707708
nullptr,
@@ -1613,7 +1614,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_mscorlib =
16131614

16141615
#if (NANOCLR_REFLECTION == TRUE)
16151616

1616-
0xF1828DE7,
1617+
0x4619DD1E,
16171618

16181619
#elif (NANOCLR_REFLECTION == FALSE)
16191620

@@ -1624,7 +1625,7 @@ const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_mscorlib =
16241625
#endif
16251626

16261627
method_lookup,
1627-
{ 100, 22, 0, 0 }
1628+
{ 100, 22, 0, 1 }
16281629
};
16291630

16301631
// clang-format on

src/CLR/CorLib/corlib_native.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,7 @@ struct Library_corlib_native_System_ReadOnlySpan_1
786786
static const int FIELD___length = 2;
787787

788788
NANOCLR_NATIVE_DECLARE(_ctor___VOID__VOIDptr__I4);
789+
NANOCLR_NATIVE_DECLARE(CopyTo___VOID__SystemSpan_1);
789790
NANOCLR_NATIVE_DECLARE(NativeReadOnlySpanConstructor___VOID__SZARRAY_GENERICTYPE__I4__I4);
790791

791792
//--//

src/CLR/CorLib/corlib_native_System_ReadOnlySpan_1.cpp

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "CorLib.h"
88

99
typedef Library_corlib_native_System_Runtime_CompilerServices_RuntimeHelpers RuntimeHelpers;
10+
typedef Library_corlib_native_System_Span_1 Span_1;
1011

1112
HRESULT Library_corlib_native_System_ReadOnlySpan_1::_ctor___VOID__VOIDptr__I4(CLR_RT_StackFrame &stack)
1213
{
@@ -64,12 +65,11 @@ HRESULT Library_corlib_native_System_ReadOnlySpan_1::_ctor___VOID__VOIDptr__I4(C
6465
}
6566

6667
// check if T is a reference type or contains references
67-
NANOCLR_CHECK_HRESULT(
68-
RuntimeHelpers::CheckReferenceOrContainsReferences(
69-
element.Class,
70-
element.DataType,
71-
&parser,
72-
isRefContainsRefs));
68+
NANOCLR_CHECK_HRESULT(RuntimeHelpers::CheckReferenceOrContainsReferences(
69+
element.Class,
70+
element.DataType,
71+
&parser,
72+
isRefContainsRefs));
7373

7474
if (isRefContainsRefs)
7575
{
@@ -105,6 +105,47 @@ HRESULT Library_corlib_native_System_ReadOnlySpan_1::_ctor___VOID__VOIDptr__I4(C
105105
NANOCLR_NOCLEANUP();
106106
}
107107

108+
HRESULT Library_corlib_native_System_ReadOnlySpan_1::CopyTo___VOID__SystemSpan_1(CLR_RT_StackFrame &stack)
109+
{
110+
NANOCLR_HEADER();
111+
112+
CLR_RT_HeapBlock_Array *sourceArray;
113+
CLR_RT_HeapBlock_Array *destinationArray;
114+
CLR_RT_HeapBlock *thisSpan = stack.This();
115+
CLR_RT_HeapBlock *destinationSpan = stack.Arg1().Dereference();
116+
117+
// check lengths - destination must be at least as large as source
118+
if (thisSpan[FIELD___length].NumericByRefConst().u4 >
119+
destinationSpan[Span_1::FIELD___length].NumericByRefConst().u4)
120+
{
121+
NANOCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
122+
}
123+
124+
// get pointers to the arrays
125+
sourceArray = thisSpan[FIELD___array].DereferenceArray();
126+
destinationArray = destinationSpan[Span_1::FIELD___array].DereferenceArray();
127+
128+
{
129+
// sanity check for empty source array
130+
if (thisSpan[FIELD___length].NumericByRefConst().s4 == 0)
131+
{
132+
NANOCLR_SET_AND_LEAVE(S_OK);
133+
}
134+
135+
// prevent GC from moving the arrays while we copy the data
136+
CLR_RT_ProtectFromGC gc1(*sourceArray);
137+
CLR_RT_ProtectFromGC gc2(*destinationArray);
138+
139+
// use memmove to safely handle potential overlapping memory regions
140+
memmove(
141+
destinationArray->GetElement(0),
142+
sourceArray->GetElement(0),
143+
thisSpan[FIELD___length].NumericByRefConst().s4 * sourceArray->m_sizeOfElement);
144+
}
145+
146+
NANOCLR_NOCLEANUP();
147+
}
148+
108149
HRESULT Library_corlib_native_System_ReadOnlySpan_1::NativeReadOnlySpanConstructor___VOID__SZARRAY_GENERICTYPE__I4__I4(
109150
CLR_RT_StackFrame &stack)
110151
{

0 commit comments

Comments
 (0)