Updates referencesource to .NET 4.7
[mono.git] / mcs / class / referencesource / mscorlib / system / reflection / emit / methodrental.cs
1 // ==++==
2 // 
3 //   Copyright (c) Microsoft Corporation.  All rights reserved.
4 // 
5 // ==--==
6 /*============================================================
7 **
8 ** Class:  MethodRental
9 **
10 ** <OWNER>Microsoft</OWNER>
11 **
12 **
13 ** MethodRental class is to provide a fast way to swap method body implementation
14 **  given a method of a class
15 **
16 ** 
17 ===========================================================*/
18 namespace System.Reflection.Emit {
19     
20     using System;
21     using System.Reflection;
22     using System.Threading;
23     using System.Runtime.CompilerServices;
24     using System.Security.Permissions;
25     using System.Runtime.InteropServices;
26     using System.Runtime.Versioning;
27     using System.Globalization;
28     using System.Security;
29     using System.Diagnostics.Contracts;
30
31     // MethodRental class provides the ability to insert a new method body of an 
32     // existing method on a class defined in a DynamicModule.
33     // Can throw OutOfMemory exception.
34     // 
35     //This class contains only static methods and does not require serialization.
36     [HostProtection(MayLeakOnAbort = true)]
37     [ClassInterface(ClassInterfaceType.None)]
38     [ComDefaultInterface(typeof(_MethodRental))]
39 [System.Runtime.InteropServices.ComVisible(true)]
40     sealed public class MethodRental : _MethodRental
41     {
42         public const int JitOnDemand            = 0x0000;        // jit the method body when it is necessary
43         public const int JitImmediate        = 0x0001;        // jit the method body now 
44     
45         [System.Security.SecuritySafeCritical]  // auto-generated
46         [SecurityPermissionAttribute(SecurityAction.Demand, UnmanagedCode=true)]
47         [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
48         public static void SwapMethodBody(
49             Type    cls,            // [in] class containing the method
50             int     methodtoken,    // [in] method token
51             IntPtr  rgIL,           // [in] pointer to bytes
52             int     methodSize,     // [in] the size of the new method body in bytes
53             int     flags)          // [in] flags
54         {
55             if (methodSize <= 0 || methodSize >= 0x3f0000)
56                 throw new ArgumentException(Environment.GetResourceString("Argument_BadSizeForData"), "methodSize");
57
58             if (cls==null)
59                 throw new ArgumentNullException("cls");
60             Contract.EndContractBlock();
61
62             Module module = cls.Module;
63             InternalModuleBuilder internalMB;
64             ModuleBuilder mb = module as ModuleBuilder;
65             if (mb != null)
66                 internalMB = mb.InternalModule;
67             else
68                 internalMB = module as InternalModuleBuilder;
69
70             // can only swap method body on dynamic module
71             // dynamic internal module type is always exactly InternalModuleBuilder, non-dynamic is always something different
72             if (internalMB == null)
73                 throw new NotSupportedException(Environment.GetResourceString("NotSupported_NotDynamicModule"));
74
75             RuntimeType rType;
76
77             if (cls is TypeBuilder)
78             {
79                 // If it is a TypeBuilder, make sure that TypeBuilder is already been baked.
80                 TypeBuilder typeBuilder = (TypeBuilder) cls;
81                 if (!typeBuilder.IsCreated())
82                     throw new NotSupportedException(Environment.GetResourceString("NotSupported_NotAllTypesAreBaked", typeBuilder.Name)); 
83                     
84                 // get the corresponding runtime type for the TypeBuilder.
85                 rType = typeBuilder.BakedRuntimeType;
86                 
87             }
88             else
89             {
90                 rType = cls as RuntimeType;
91             }
92
93             if (rType == null)
94                 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "cls");
95
96             StackCrawlMark mark = StackCrawlMark.LookForMyCaller;
97
98             RuntimeAssembly rtAssembly = internalMB.GetRuntimeAssembly();
99             lock (rtAssembly.SyncRoot)
100             {
101                 SwapMethodBody(rType.GetTypeHandleInternal(), methodtoken, rgIL, methodSize, flags, JitHelpers.GetStackCrawlMarkHandle(ref mark));
102             }
103         }
104     
105         [System.Security.SecurityCritical]  // auto-generated
106         [ResourceExposure(ResourceScope.None)]
107         [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
108         [SuppressUnmanagedCodeSecurity]
109         private extern static void SwapMethodBody(
110             RuntimeTypeHandle cls,            // [in] class containing the method
111             int            methodtoken,        // [in] method token
112             IntPtr        rgIL,                // [in] pointer to bytes
113             int            methodSize,            // [in] the size of the new method body in bytes
114             int         flags,              // [in] flags
115             StackCrawlMarkHandle stackMark); // [in] stack crawl mark used to find caller
116
117         // private constructor to prevent class to be constructed.
118         private MethodRental() {}
119
120
121         void _MethodRental.GetTypeInfoCount(out uint pcTInfo)
122         {
123             throw new NotImplementedException();
124         }
125
126         void _MethodRental.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
127         {
128             throw new NotImplementedException();
129         }
130
131         void _MethodRental.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
132         {
133             throw new NotImplementedException();
134         }
135
136         void _MethodRental.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
137         {
138             throw new NotImplementedException();
139         }
140
141     }
142 }