using System.Runtime.Versioning;
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif
+
namespace System.Runtime.CompilerServices
{
//
}
/// <summary>
+ /// Adds an element offset to the given reference.
+ /// </summary>
+ [NonVersionable]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref T AddNative<T>(ref T source, nuint elementOffset)
+ {
+ // The body of this function will be replaced by the EE with unsafe code!!!
+ // See getILIntrinsicImplementationForUnsafe for how this happens.
+ typeof(T).ToString(); // Type used by the actual method body
+ throw new InvalidOperationException();
+ }
+
+ /// <summary>
/// Determines whether the specified references point to the same location.
/// </summary>
[NonVersionable]
}
// P/Invoke into the native version for large lengths
- if (byteLength >= 512)
- {
- RuntimeImports.RhZeroMemory(ref b, byteLength);
- return;
- }
+ if (byteLength >= 512) goto PInvoke;
nuint i = 0; // byte offset at which we're copying
// We're not using i after this, so not needed
// i += 1;
}
+
+ return;
+
+ PInvoke:
+ RuntimeImports.RhZeroMemory(ref b, byteLength);
}
internal static unsafe void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLength)
nuint n = 0;
while ((n = i + 8) <= (pointerSizeLength))
{
- Unsafe.Add<IntPtr>(ref ip, (int)i + 0) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 1) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 2) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 3) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 4) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 5) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 6) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 7) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 0) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 1) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 2) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 3) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 4) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 5) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 6) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 7) = default(IntPtr);
i = n;
}
if ((n = i + 4) <= (pointerSizeLength))
{
- Unsafe.Add<IntPtr>(ref ip, (int)i + 0) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 1) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 2) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 3) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 0) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 1) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 2) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 3) = default(IntPtr);
i = n;
}
if ((n = i + 2) <= (pointerSizeLength))
{
- Unsafe.Add<IntPtr>(ref ip, (int)i + 0) = default(IntPtr);
- Unsafe.Add<IntPtr>(ref ip, (int)i + 1) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 0) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i + 1) = default(IntPtr);
i = n;
}
if ((i + 1) <= (pointerSizeLength))
{
- Unsafe.Add<IntPtr>(ref ip, (int)i) = default(IntPtr);
+ Unsafe.AddNative<IntPtr>(ref ip, i) = default(IntPtr);
}
}
-
- [StructLayout(LayoutKind.Sequential, Size = 64)]
- private struct Reg64 { }
- [StructLayout(LayoutKind.Sequential, Size = 32)]
- private struct Reg32 { }
- [StructLayout(LayoutKind.Sequential, Size = 16)]
- private struct Reg16 { }
}
}
methInfo->options = (CorInfoOptions)0;
return true;
}
+ else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ADD_NATIVE)->GetMemberDef())
+ {
+ mdToken tokGenericArg = FindGenericMethodArgTypeSpec(MscorlibBinder::GetModule()->GetMDImport());
+
+ static BYTE ilcode[] = { CEE_LDARG_0, CEE_LDARG_1,
+ CEE_PREFIX1, (CEE_SIZEOF & 0xFF), 0,0,0,0,
+ CEE_MUL,
+ CEE_ADD,
+ CEE_RET };
+
+ ilcode[4] = (BYTE)(tokGenericArg);
+ ilcode[5] = (BYTE)(tokGenericArg >> 8);
+ ilcode[6] = (BYTE)(tokGenericArg >> 16);
+ ilcode[7] = (BYTE)(tokGenericArg >> 24);
+
+ methInfo->ILCode = const_cast<BYTE*>(ilcode);
+ methInfo->ILCodeSize = sizeof(ilcode);
+ methInfo->maxStack = 3;
+ methInfo->EHcount = 0;
+ methInfo->options = (CorInfoOptions)0;
+ return true;
+ }
else if (tk == MscorlibBinder::GetMethod(METHOD__UNSAFE__BYREF_ARE_SAME)->GetMemberDef())
{
// Compare the two arguments
DEFINE_METHOD(UNSAFE, SIZEOF, SizeOf, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_AS, As, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ADD, Add, NoSig)
+DEFINE_METHOD(UNSAFE, BYREF_ADD_NATIVE, AddNative, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_ARE_SAME, AreSame, NoSig)
DEFINE_METHOD(UNSAFE, BYREF_INIT_BLOCK_UNALIGNED, InitBlockUnaligned, NoSig)