blob: b8bb7c498184c24317226a8c37d7ebc5f96abc2f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
////////////////////////////////////////////////////////////////////////////////
// JitHelpers
// Low-level Jit Helpers
////////////////////////////////////////////////////////////////////////////////
using System.Threading;
using System.Diagnostics;
using Internal.Runtime.CompilerServices;
namespace System.Runtime.CompilerServices
{
// Wrapper for address of a string variable on stack
internal struct StringHandleOnStack
{
private IntPtr m_ptr;
internal StringHandleOnStack(IntPtr pString)
{
m_ptr = pString;
}
}
// Wrapper for address of a object variable on stack
internal struct ObjectHandleOnStack
{
private IntPtr m_ptr;
internal ObjectHandleOnStack(IntPtr pObject)
{
m_ptr = pObject;
}
}
// Wrapper for StackCrawlMark
internal struct StackCrawlMarkHandle
{
private IntPtr m_ptr;
internal StackCrawlMarkHandle(IntPtr stackMark)
{
m_ptr = stackMark;
}
}
// Helper class to assist with unsafe pinning of arbitrary objects.
// It's used by VM code.
internal class RawData
{
public byte Data;
}
internal class RawSzArrayData
{
public IntPtr Count; // Array._numComponents padded to IntPtr
public byte Data;
}
internal static unsafe class JitHelpers
{
// The special dll name to be used for DllImport of QCalls
internal const string QCall = "QCall";
// Wraps object variable into a handle. Used to return managed strings from QCalls.
// s has to be a local variable on the stack.
internal static StringHandleOnStack GetStringHandleOnStack(ref string s)
{
return new StringHandleOnStack((IntPtr)Unsafe.AsPointer(ref s));
}
// Wraps object variable into a handle. Used to pass managed object references in and out of QCalls.
// o has to be a local variable on the stack.
internal static ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T : class
{
return new ObjectHandleOnStack((IntPtr)Unsafe.AsPointer(ref o));
}
// Wraps StackCrawlMark into a handle. Used to pass StackCrawlMark to QCalls.
// stackMark has to be a local variable on the stack.
internal static StackCrawlMarkHandle GetStackCrawlMarkHandle(ref StackCrawlMark stackMark)
{
return new StackCrawlMarkHandle((IntPtr)Unsafe.AsPointer(ref stackMark));
}
internal static bool EnumEquals<T>(T x, T y) where T : struct, Enum
{
// The body of this function will be replaced by the EE with unsafe code
// See getILIntrinsicImplementation for how this happens.
return x.Equals(y);
}
internal static int EnumCompareTo<T>(T x, T y) where T : struct, Enum
{
// The body of this function will be replaced by the EE with unsafe code
// See getILIntrinsicImplementation for how this happens.
return x.CompareTo(y);
}
// Set the given element in the array without any type or range checks
[MethodImplAttribute(MethodImplOptions.InternalCall)]
internal static extern void UnsafeSetArrayElement(object[] target, int index, object element);
internal static ref byte GetRawData(this object obj) =>
ref Unsafe.As<RawData>(obj).Data;
internal static ref byte GetRawSzArrayData(this Array array) =>
ref Unsafe.As<RawSzArrayData>(array).Data;
}
}
|