3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>Microsoft</OWNER>
13 ** MethodRental class is to provide a fast way to swap method body implementation
14 ** given a method of a class
17 ===========================================================*/
18 namespace System.Reflection.Emit {
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;
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.
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
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
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
55 if (methodSize <= 0 || methodSize >= 0x3f0000)
56 throw new ArgumentException(Environment.GetResourceString("Argument_BadSizeForData"), "methodSize");
59 throw new ArgumentNullException("cls");
60 Contract.EndContractBlock();
62 Module module = cls.Module;
63 InternalModuleBuilder internalMB;
64 ModuleBuilder mb = module as ModuleBuilder;
66 internalMB = mb.InternalModule;
68 internalMB = module as InternalModuleBuilder;
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"));
77 if (cls is TypeBuilder)
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));
84 // get the corresponding runtime type for the TypeBuilder.
85 rType = typeBuilder.BakedRuntimeType;
90 rType = cls as RuntimeType;
94 throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "cls");
96 StackCrawlMark mark = StackCrawlMark.LookForMyCaller;
98 RuntimeAssembly rtAssembly = internalMB.GetRuntimeAssembly();
99 lock (rtAssembly.SyncRoot)
101 SwapMethodBody(rType.GetTypeHandleInternal(), methodtoken, rgIL, methodSize, flags, JitHelpers.GetStackCrawlMarkHandle(ref mark));
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
117 // private constructor to prevent class to be constructed.
118 private MethodRental() {}
121 void _MethodRental.GetTypeInfoCount(out uint pcTInfo)
123 throw new NotImplementedException();
126 void _MethodRental.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
128 throw new NotImplementedException();
131 void _MethodRental.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
133 throw new NotImplementedException();
136 void _MethodRental.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
138 throw new NotImplementedException();