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

Delegate.DefaultParameters.cs « System « src « System.Private.CoreLib « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 8460fb8fade19ac035b32aab035d298763e84298 (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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
// 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 System.Runtime;

namespace System
{
    public abstract partial class Delegate
    {
        // Default parameter support
        private const int DefaultParamTypeNone = 0;
        private const int DefaultParamTypeBool = 1;
        private const int DefaultParamTypeChar = 2;
        private const int DefaultParamTypeI1 = 3;
        private const int DefaultParamTypeI2 = 4;
        private const int DefaultParamTypeI4 = 5;
        private const int DefaultParamTypeI8 = 6;
        private const int DefaultParamTypeR4 = 7;
        private const int DefaultParamTypeR8 = 8;
        private const int DefaultParamTypeString = 9;
        private const int DefaultParamTypeDefault = 10;
        private const int DefaultParamTypeDecimal = 11;
        private const int DefaultParamTypeDateTime = 12;
        private const int DefaultParamTypeNoneButOptional = 13;
        private const int DefaultParamTypeUI1 = 14;
        private const int DefaultParamTypeUI2 = 15;
        private const int DefaultParamTypeUI4 = 16;
        private const int DefaultParamTypeUI8 = 17;

        private struct StringDataParser
        {
            private string _str;
            private int _offset;
            public StringDataParser(string str)
            {
                _str = str;
                _offset = 0;
            }

            public void SetOffset(int offset)
            {
                _offset = offset;
            }

            public long GetLong()
            {
                long returnValue;

                char curVal = _str[_offset++];

                // Special encoding for MinInt is 0x0001 (which would normally mean -0).
                if (curVal == 0x0001)
                {
                    return long.MinValue;
                }

                // High bit is used to indicate an extended value
                // Low bit is sign bit
                // The middle 14 bits are used to hold 14 bits of the actual long value.
                // A sign bit approach is used so that a negative number can be represented with 1 char value.
                returnValue = (long)(curVal & (char)0x7FFE);
                returnValue = returnValue >> 1;
                bool isNegative = ((curVal & (char)1)) == 1;
                int additionalCharCount = 0;
                int bitsAcquired = 14;
                // For additional characters, the first 3 additional characters hold 15 bits of data
                // and the last character may hold 5 bits of data.
                while ((curVal & (char)0x8000) != 0)
                {
                    additionalCharCount++;
                    curVal = _str[_offset++];
                    long grabValue = (long)(curVal & (char)0x7FFF);
                    grabValue <<= bitsAcquired;
                    bitsAcquired += 15;
                    returnValue |= grabValue;
                }

                if (isNegative)
                    returnValue = -returnValue;

                return returnValue;
            }

            public int GetInt()
            {
                return checked((int)GetLong());
            }

            public unsafe float GetFloat()
            {
                int inputLocation = checked((int)GetLong());
                float result = 0;
                byte* inputPtr = (byte*)&inputLocation;
                byte* outputPtr = (byte*)&result;
                for (int i = 0; i < 4; i++)
                {
                    outputPtr[i] = inputPtr[i];
                }

                return result;
            }

            public unsafe double GetDouble()
            {
                long inputLocation = GetLong();
                double result = 0;
                byte* inputPtr = (byte*)&inputLocation;
                byte* outputPtr = (byte*)&result;
                for (int i = 0; i < 8; i++)
                {
                    outputPtr[i] = inputPtr[i];
                }

                return result;
            }

            public unsafe string GetString()
            {
                fixed (char* strData = _str)
                {
                    int length = (int)GetLong();
                    char c = _str[_offset]; // Check for index out of range concerns.
                    string strRet = new string(strData, _offset, length);
                    _offset += length;

                    return strRet;
                }
            }

            public void Skip(int count)
            {
                _offset += count;
            }
        }

        /// <summary>
        /// Retrieves the default value for a parameter of the delegate.
        /// </summary>
        /// <param name="thType">The type of the parameter to retrieve.</param>
        /// <param name="argIndex">The index of the parameter on the method to retrieve.</param>
        /// <param name="defaultValue">The default value of the parameter if available.</param>
        /// <returns>true if the default parameter value is available, otherwise false.</returns>
        internal bool TryGetDefaultParameterValue(RuntimeTypeHandle thType, int argIndex, out object defaultValue)
        {
            defaultValue = null;

            // The LoadDefaultValueString() has the following contract
            // If it returns false, the delegate invoke does not have default values.
            // If it returns true, then the s_DefaultValueString variable is set to 
            // describe the default values for this invoke.
            string defaultValueString = null;
            if (LoadDefaultValueString())
            {
                defaultValueString = s_DefaultValueString;
            }

            // Group index of 0 indicates there are no default parameters
            if (defaultValueString == null)
            {
                return false;
            }
            StringDataParser dataParser = new StringDataParser(defaultValueString);

            // Skip to current argument
            int curArgIndex = 0;
            while (curArgIndex != argIndex)
            {
                int skip = dataParser.GetInt();
                dataParser.Skip(skip);
                curArgIndex++;
            }

            // Discard size of current argument
            int sizeOfCurrentArg = dataParser.GetInt();

            int defaultValueType = dataParser.GetInt();

            switch (defaultValueType)
            {
                case DefaultParamTypeNone:
                default:
                    return false;

                case DefaultParamTypeString:
                    defaultValue = dataParser.GetString();
                    return true;

                case DefaultParamTypeDefault:
                    if (thType.ToEETypePtr().IsValueType)
                    {
                        if (thType.ToEETypePtr().IsNullable)
                        {
                            defaultValue = null;
                            return true;
                        }
                        else
                        {
                            defaultValue = RuntimeImports.RhNewObject(thType.ToEETypePtr());
                            return true;
                        }
                    }
                    else
                    {
                        defaultValue = null;
                        return true;
                    }

                case DefaultParamTypeBool:
                    defaultValue = (dataParser.GetInt() == 1);
                    return true;
                case DefaultParamTypeChar:
                    defaultValue = (char)dataParser.GetInt();
                    return true;
                case DefaultParamTypeI1:
                    defaultValue = (sbyte)dataParser.GetInt();
                    return true;
                case DefaultParamTypeUI1:
                    defaultValue = (byte)dataParser.GetInt();
                    return true;
                case DefaultParamTypeI2:
                    defaultValue = (short)dataParser.GetInt();
                    return true;
                case DefaultParamTypeUI2:
                    defaultValue = (ushort)dataParser.GetInt();
                    return true;
                case DefaultParamTypeI4:
                    defaultValue = dataParser.GetInt();
                    return true;
                case DefaultParamTypeUI4:
                    defaultValue = checked((uint)dataParser.GetLong());
                    return true;
                case DefaultParamTypeI8:
                    defaultValue = dataParser.GetLong();
                    return true;
                case DefaultParamTypeUI8:
                    defaultValue = (ulong)dataParser.GetLong();
                    return true;
                case DefaultParamTypeR4:
                    defaultValue = dataParser.GetFloat();
                    return true;
                case DefaultParamTypeR8:
                    defaultValue = dataParser.GetDouble();
                    return true;
                case DefaultParamTypeDecimal:
                    int[] decimalBits = new int[4];
                    decimalBits[0] = dataParser.GetInt();
                    decimalBits[1] = dataParser.GetInt();
                    decimalBits[2] = dataParser.GetInt();
                    decimalBits[3] = dataParser.GetInt();
                    defaultValue = new decimal(decimalBits);
                    return true;
                case DefaultParamTypeDateTime:
                    defaultValue = new DateTime(dataParser.GetLong());
                    return true;
                case DefaultParamTypeNoneButOptional:
                    defaultValue = System.Reflection.Missing.Value;
                    return true;
            }
        }
    }
}