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

MethodDesc.RuntimeDetermined.cs « RuntimeDetermined « TypeSystem « src « Common « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: ad83c69f670f0463c874aa98a9387e28c959b334 (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
// 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.

using Debug = System.Diagnostics.Debug;

namespace Internal.TypeSystem
{
    partial class MethodDesc
    {
        /// <summary>
        /// Gets the shared runtime determined form of the method. This is a canonical form of the method
        /// where generic arguments of the method and the owning type have been converted to runtime determined types.
        /// </summary>
        public MethodDesc GetSharedRuntimeFormMethodTarget()
        {
            MethodDesc result = this;

            DefType owningType = OwningType as DefType;
            if (owningType != null)
            {
                // First find the method on the shared runtime form of the owning type
                DefType sharedRuntimeOwningType = owningType.ConvertToSharedRuntimeDeterminedForm();
                if (sharedRuntimeOwningType != owningType)
                {
                    result = Context.GetMethodForInstantiatedType(
                        GetTypicalMethodDefinition(), (InstantiatedType)sharedRuntimeOwningType);
                }

                // Now convert the method instantiation to the shared runtime form
                if (result.HasInstantiation)
                {
                    MethodDesc uninstantiatedMethod = result.GetMethodDefinition();

                    bool changed;
                    Instantiation sharedInstantiation = RuntimeDeterminedTypeUtilities.ConvertInstantiationToSharedRuntimeForm(
                        Instantiation, uninstantiatedMethod.Instantiation, out changed);

                    // If either the instantiation changed, or we switched the owning type, we need to find the matching
                    // instantiated method.
                    if (changed || result != this)
                    {
                        result = Context.GetInstantiatedMethod(uninstantiatedMethod, sharedInstantiation);
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// Gets the type which holds the implementation of this method. This is typically the owning method,
        /// unless this method models a target of a constrained method call.
        /// </summary>
        public TypeDesc ImplementationType
        {
            get
            {
                // TODO: IsConstrainedMethod
                return OwningType;
            }
        }

        /// <summary>
        /// Gets a value indicating whether this is a shared method body.
        /// </summary>
        public bool IsSharedByGenericInstantiations
        {
            get
            {
                return IsCanonicalMethod(CanonicalFormKind.Any);
            }
        }

        /// <summary>
        /// Gets a value indicating whether this is a canonical method that will only become concrete
        /// at runtime (after supplying the generic context).
        /// </summary>
        public bool IsRuntimeDeterminedExactMethod
        {
            get
            {
                TypeDesc containingType = ImplementationType;
                if (containingType.IsRuntimeDeterminedSubtype)
                    return true;

                foreach (TypeDesc typeArg in Instantiation)
                {
                    if (typeArg.IsRuntimeDeterminedSubtype)
                        return true;
                }

                return false;
            }
        }

        public virtual MethodDesc GetNonRuntimeDeterminedMethodFromRuntimeDeterminedMethodViaSubstitution(Instantiation typeInstantiation, Instantiation methodInstantiation)
        {
            Instantiation instantiation = Instantiation;
            TypeDesc[] clone = null;

            for (int i = 0; i < instantiation.Length; i++)
            {
                TypeDesc uninst = instantiation[i];
                TypeDesc inst = uninst.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(typeInstantiation, methodInstantiation);
                if (inst != uninst)
                {
                    if (clone == null)
                    {
                        clone = new TypeDesc[instantiation.Length];
                        for (int j = 0; j < clone.Length; j++)
                        {
                            clone[j] = instantiation[j];
                        }
                    }
                    clone[i] = inst;
                }
            }

            MethodDesc method = this;

            TypeDesc owningType = method.OwningType;
            TypeDesc instantiatedOwningType = owningType.GetNonRuntimeDeterminedTypeFromRuntimeDeterminedSubtypeViaSubstitution(typeInstantiation, methodInstantiation);
            if (owningType != instantiatedOwningType)
            {
                method = Context.GetMethodForInstantiatedType(method.GetTypicalMethodDefinition(), (InstantiatedType)instantiatedOwningType);
                if (clone == null && instantiation.Length != 0)
                    return Context.GetInstantiatedMethod(method, instantiation);
            }

            return (clone == null) ? method : Context.GetInstantiatedMethod(method.GetMethodDefinition(), new Instantiation(clone));
        }
    }
}