-
Notifications
You must be signed in to change notification settings - Fork 63
/
Copy pathMiniRuntime.cs
147 lines (133 loc) · 5.93 KB
/
MiniRuntime.cs
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
namespace Internal.Runtime.CompilerHelpers
{
// A class that the compiler looks for that has helpers to initialize the
// process. The compiler can gracefully handle the helpers not being present,
// but the class itself being absent is unhandled. Let's add an empty class.
class StartupCodeHelpers
{
[System.Runtime.RuntimeExport("RhpReversePInvoke2")]
static void RhpReversePInvoke2(System.IntPtr frame) { }
[System.Runtime.RuntimeExport("RhpReversePInvokeReturn2")]
static void RhpReversePInvokeReturn2(System.IntPtr frame) { }
[System.Runtime.RuntimeExport("RhpPInvoke")]
static void RhpPinvoke(System.IntPtr frame) { }
[System.Runtime.RuntimeExport("RhpPInvokeReturn")]
static void RhpPinvokeReturn(System.IntPtr frame) { }
}
}
namespace System
{
class Array<T> : Array { }
}
namespace System.Runtime
{
// Custom attribute that the compiler understands that instructs it
// to export the method under the given symbolic name.
internal sealed class RuntimeExportAttribute : Attribute
{
public RuntimeExportAttribute(string entry) { }
}
}
namespace System.Runtime.InteropServices
{
public class UnmanagedType { }
// Custom attribute that marks a class as having special "Call" intrinsics.
internal class McgIntrinsicsAttribute : Attribute { }
internal enum OSPlatform
{
Windows,
Linux,
}
}
namespace System.Runtime.CompilerServices
{
// A class responsible for running static constructors. The compiler will call into this
// code to ensure static constructors run and that they only run once.
[System.Runtime.InteropServices.McgIntrinsics]
internal static class ClassConstructorRunner
{
private static unsafe IntPtr CheckStaticClassConstructionReturnNonGCStaticBase(ref StaticClassConstructionContext context, IntPtr nonGcStaticBase)
{
CheckStaticClassConstruction(ref context);
return nonGcStaticBase;
}
private static unsafe void CheckStaticClassConstruction(ref StaticClassConstructionContext context)
{
// Very simplified class constructor runner. In real world, the class constructor runner
// would need to be able to deal with potentially multiple threads racing to initialize
// a single class, and would need to be able to deal with potential deadlocks
// between class constructors.
if (context.initialized == 1)
return;
context.initialized = 1;
// Run the class constructor.
Call<int>(context.cctorMethodAddress);
}
// This is a special compiler intrinsic that calls method pointed to by pfn.
[System.Runtime.CompilerServices.Intrinsic]
public static extern T Call<T>(System.IntPtr pfn);
}
// This data structure is a contract with the compiler. It holds the address of a static
// constructor and a flag that specifies whether the constructor already executed.
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct StaticClassConstructionContext
{
// Pointer to the code for the static class constructor method. This is initialized by the
// binder/runtime.
public IntPtr cctorMethodAddress;
// Initialization state of the class. This is initialized to 0. Every time managed code checks the
// cctor state the runtime will call the classlibrary's CheckStaticClassConstruction with this context
// structure unless initialized == 1. This check is specific to allow the classlibrary to store more
// than a binary state for each cctor if it so desires.
public int initialized;
}
[System.Runtime.InteropServices.McgIntrinsicsAttribute]
internal class RawCalliHelper
{
public static unsafe ulong StdCall<T, U, W, X>(IntPtr pfn, T* arg1, U* arg2, W* arg3, X* arg4) where T : unmanaged where U : unmanaged where W : unmanaged where X : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T, U, W, X>(IntPtr pfn, T arg1, U* arg2, W* arg3, X* arg4) where T : struct where U : unmanaged where W : unmanaged where X : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T, U, W>(IntPtr pfn, T* arg1, U* arg2, W* arg3) where T : unmanaged where U : unmanaged where W : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T, U, W>(IntPtr pfn, T arg1, U* arg2, W* arg3) where T : unmanaged where U : unmanaged where W : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T, U, W>(IntPtr pfn, T* arg1, U arg2, W arg3) where T : unmanaged where U : unmanaged where W : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T, U>(IntPtr pfn, T* arg1, U* arg2) where T : unmanaged where U : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T, U>(IntPtr pfn, T* arg1, U arg2) where T : unmanaged where U : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T>(IntPtr pfn, T* arg1) where T : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
public static unsafe ulong StdCall<T>(IntPtr pfn, T arg1) where T : unmanaged
{
// This will be filled in by an IL transform
return 0;
}
}
}