Welcome to mirror list, hosted at ThFree Co, Russian Federation.

methodrental.cs « emit « reflection « system « mscorlib « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c4e980c9549a090b78faa705c8ee32b0dfe237dc (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
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
// ==++==
// 
//   Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// ==--==
/*============================================================
**
** Class:  MethodRental
**
** <OWNER>Microsoft</OWNER>
**
**
** MethodRental class is to provide a fast way to swap method body implementation
**  given a method of a class
**
** 
===========================================================*/
namespace System.Reflection.Emit {
    
    using System;
    using System.Reflection;
    using System.Threading;
    using System.Runtime.CompilerServices;
    using System.Security.Permissions;
    using System.Runtime.InteropServices;
    using System.Runtime.Versioning;
    using System.Globalization;
    using System.Security;
    using System.Diagnostics.Contracts;

    // MethodRental class provides the ability to insert a new method body of an 
    // existing method on a class defined in a DynamicModule.
    // Can throw OutOfMemory exception.
    // 
    //This class contains only static methods and does not require serialization.
    [HostProtection(MayLeakOnAbort = true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(_MethodRental))]
[System.Runtime.InteropServices.ComVisible(true)]
    sealed public class MethodRental : _MethodRental
    {
        public const int JitOnDemand            = 0x0000;        // jit the method body when it is necessary
        public const int JitImmediate        = 0x0001;        // jit the method body now 
    
        [System.Security.SecuritySafeCritical]  // auto-generated
        [SecurityPermissionAttribute(SecurityAction.Demand, UnmanagedCode=true)]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public static void SwapMethodBody(
            Type    cls,            // [in] class containing the method
            int     methodtoken,    // [in] method token
            IntPtr  rgIL,           // [in] pointer to bytes
            int     methodSize,     // [in] the size of the new method body in bytes
            int     flags)          // [in] flags
        {
            if (methodSize <= 0 || methodSize >= 0x3f0000)
                throw new ArgumentException(Environment.GetResourceString("Argument_BadSizeForData"), "methodSize");

            if (cls==null)
                throw new ArgumentNullException("cls");
            Contract.EndContractBlock();

            Module module = cls.Module;
            InternalModuleBuilder internalMB;
            ModuleBuilder mb = module as ModuleBuilder;
            if (mb != null)
                internalMB = mb.InternalModule;
            else
                internalMB = module as InternalModuleBuilder;

            // can only swap method body on dynamic module
            // dynamic internal module type is always exactly InternalModuleBuilder, non-dynamic is always something different
            if (internalMB == null)
                throw new NotSupportedException(Environment.GetResourceString("NotSupported_NotDynamicModule"));

            RuntimeType rType;

            if (cls is TypeBuilder)
            {
                // If it is a TypeBuilder, make sure that TypeBuilder is already been baked.
                TypeBuilder typeBuilder = (TypeBuilder) cls;
                if (!typeBuilder.IsCreated())
                    throw new NotSupportedException(Environment.GetResourceString("NotSupported_NotAllTypesAreBaked", typeBuilder.Name)); 
                    
                // get the corresponding runtime type for the TypeBuilder.
                rType = typeBuilder.BakedRuntimeType;
                
            }
            else
            {
                rType = cls as RuntimeType;
            }

            if (rType == null)
                throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "cls");

            StackCrawlMark mark = StackCrawlMark.LookForMyCaller;

            RuntimeAssembly rtAssembly = internalMB.GetRuntimeAssembly();
            lock (rtAssembly.SyncRoot)
            {
                SwapMethodBody(rType.GetTypeHandleInternal(), methodtoken, rgIL, methodSize, flags, JitHelpers.GetStackCrawlMarkHandle(ref mark));
            }
        }
    
        [System.Security.SecurityCritical]  // auto-generated
        [ResourceExposure(ResourceScope.None)]
        [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
        [SuppressUnmanagedCodeSecurity]
        private extern static void SwapMethodBody(
            RuntimeTypeHandle cls,            // [in] class containing the method
            int            methodtoken,        // [in] method token
            IntPtr        rgIL,                // [in] pointer to bytes
            int            methodSize,            // [in] the size of the new method body in bytes
            int         flags,              // [in] flags
            StackCrawlMarkHandle stackMark); // [in] stack crawl mark used to find caller

        // private constructor to prevent class to be constructed.
        private MethodRental() {}


        void _MethodRental.GetTypeInfoCount(out uint pcTInfo)
        {
            throw new NotImplementedException();
        }

        void _MethodRental.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo)
        {
            throw new NotImplementedException();
        }

        void _MethodRental.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId)
        {
            throw new NotImplementedException();
        }

        void _MethodRental.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr)
        {
            throw new NotImplementedException();
        }

    }
}