HANDLES(ARRAY_13, "SetValueImpl", ves_icall_System_Array_SetValueImpl, void, 3, (MonoArray, MonoObject, guint32))
HANDLES(ARRAY_14, "SetValueRelaxedImpl", ves_icall_System_Array_SetValueRelaxedImpl, void, 3, (MonoArray, MonoObject, guint32))
-ICALL_TYPE(BUFFER, "System.Buffer", BUFFER_1)
+ICALL_TYPE(BUFFER, "System.Buffer", BUFFER_0)
+HANDLES(BUFFER_0, "BlockCopy", ves_icall_System_Buffer_BlockCopy, void, 5, (MonoArray, int, MonoArray, int, int))
+HANDLES(BUFFER_0a, "IsPrimitiveTypeArray", ves_icall_System_Buffer_IsPrimitiveTypeArray, MonoBoolean, 1, (MonoArray))
HANDLES(BUFFER_1, "_ByteLength", ves_icall_System_Buffer_ByteLengthInternal, gint32, 1, (MonoArray))
NOHANDLES(ICALL(BUFFER_2, "__Memmove", ves_icall_System_Runtime_RuntimeImports_Memmove))
}
}
+#ifdef ENABLE_NETCORE
+void
+ves_icall_System_Buffer_BlockCopy (MonoArrayHandle src, int src_offset, MonoArrayHandle dst, int dst_offset, int count, MonoError *error)
+{
+ MONO_CHECK_ARG_NULL_HANDLE (src,);
+ MONO_CHECK_ARG_NULL_HANDLE (dst,);
+
+ if (src_offset < 0) {
+ mono_error_set_argument_out_of_range (error, "srcOffset", "Value must be non-negative and less than or equal to Int32.MaxValue.");
+ return;
+ }
+
+ if (dst_offset < 0) {
+ mono_error_set_argument_out_of_range (error, "dstOffset", "Value must be non-negative and less than or equal to Int32.MaxValue.");
+ return;
+ }
+
+ if (count < 0) {
+ mono_error_set_argument_out_of_range (error, "count", "Value must be non-negative and less than or equal to Int32.MaxValue.");
+ return;
+ }
+
+ MonoClass * const src_class = m_class_get_element_class (MONO_HANDLE_GETVAL (src, obj.vtable)->klass);
+ MonoClass * const dst_class = m_class_get_element_class (MONO_HANDLE_GETVAL (dst, obj.vtable)->klass);
+
+ if (!m_class_is_primitive (src_class)) {
+ mono_error_set_argument (error, "src", "Object must be an array of primitives.");
+ return;
+ }
+
+ if (!m_class_is_primitive (dst_class)) {
+ mono_error_set_argument (error, "dst", "Object must be an array of primitives.");
+ return;
+ }
+
+ if ((src_offset > mono_array_get_byte_length (src) - count) || (dst_offset > mono_array_get_byte_length (dst) - count)) {
+ mono_error_set_argument (error, "", "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.");
+ return;
+ }
+
+ MONO_ENTER_NO_SAFEPOINTS;
+
+ guint8 const * const src_buf = (guint8*)MONO_HANDLE_RAW (src)->vector + src_offset;
+ guint8* const dst_buf = (guint8*)MONO_HANDLE_RAW (dst)->vector + dst_offset;
+
+ memmove (dst_buf, src_buf, count);
+
+ MONO_EXIT_NO_SAFEPOINTS;
+
+ return;
+}
+
+MonoBoolean
+ves_icall_System_Buffer_IsPrimitiveTypeArray (MonoArrayHandle array, MonoError* error)
+{
+ MonoClass * const klass = m_class_get_element_class (MONO_HANDLE_GETVAL (array, obj.vtable)->klass);
+ return m_class_is_primitive (klass);
+}
+#endif
+
gint32
ves_icall_System_Buffer_ByteLengthInternal (MonoArrayHandle array, MonoError* error)
{
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Runtime;
using System.Runtime.CompilerServices;
-using Internal.Runtime.CompilerServices;
#if BIT64
using nuint = System.UInt64;
{
partial class Buffer
{
- public static void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count)
- {
- if (src == null)
- throw new ArgumentNullException (nameof (src));
- if (dst == null)
- throw new ArgumentNullException ("dst");
-
- if (srcOffset < 0)
- throw new ArgumentOutOfRangeException (nameof (srcOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32);
- if (dstOffset < 0)
- throw new ArgumentOutOfRangeException (nameof (dstOffset), SR.ArgumentOutOfRange_MustBeNonNegInt32);
- if (count < 0)
- throw new ArgumentOutOfRangeException (nameof (count), SR.ArgumentOutOfRange_MustBeNonNegInt32);
- if (!IsPrimitiveTypeArray (src))
- throw new ArgumentException (SR.Arg_MustBePrimArray, nameof (src));
- if (!IsPrimitiveTypeArray (dst))
- throw new ArgumentException (SR.Arg_MustBePrimArray, nameof (dst));
-
- var uCount = (nuint) count;
- var uSrcOffset = (nuint) srcOffset;
- var uDstOffset = (nuint) dstOffset;
-
- var uSrcLen = (nuint) ByteLength (src);
- var uDstLen = (nuint) ByteLength (dst);
-
- if (uSrcLen < uSrcOffset + uCount)
- throw new ArgumentException (SR.Argument_InvalidOffLen, "");
- if (uDstLen < uDstOffset + uCount)
- throw new ArgumentException (SR.Argument_InvalidOffLen, "");
-
- if (uCount != 0) {
- unsafe {
- fixed (byte* pSrc = &src.GetRawArrayData (), pDst = &dst.GetRawArrayData ()) {
- Memmove (pDst + uDstOffset, pSrc + uSrcOffset, uCount);
- }
- }
- }
- }
+ [MethodImpl (MethodImplOptions.InternalCall)]
+ public static extern void BlockCopy (Array src, int srcOffset, Array dst, int dstOffset, int count);
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ [MethodImpl (MethodImplOptions.InternalCall)]
static extern int _ByteLength (Array array);
- static bool IsPrimitiveTypeArray (Array array)
- {
- // TODO: optimize
- return array.GetType ().GetElementType ()!.IsPrimitive;
- }
+ [MethodImpl (MethodImplOptions.InternalCall)]
+ static extern bool IsPrimitiveTypeArray (Array array);
internal static unsafe void Memcpy (byte* dest, byte* src, int len) => Memmove (dest, src, (nuint) len);