PageRenderTime 38ms CodeModel.GetById 27ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 1ms

/Microsoft.Scripting.Core/Actions/CallSiteRule.cs

https://bitbucket.org/stefanrusek/xronos
C# | 186 lines | 110 code | 23 blank | 53 comment | 8 complexity | 405fd3cb8251f489e54d1cf37aa8a032 MD5 | raw file
  1/* ****************************************************************************
  2 *
  3 * Copyright (c) Microsoft Corporation. 
  4 *
  5 * This source code is subject to terms and conditions of the Microsoft Public License. A 
  6 * copy of the license can be found in the License.html file at the root of this distribution. If 
  7 * you cannot locate the  Microsoft Public License, please send an email to 
  8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
  9 * by the terms of the Microsoft Public License.
 10 *
 11 * You must not remove this notice, or any other, from this software.
 12 *
 13 *
 14 * ***************************************************************************/
 15using System; using Microsoft;
 16
 17
 18using System.Collections.ObjectModel;
 19using System.ComponentModel;
 20using System.Diagnostics;
 21#if CODEPLEX_40
 22using System.Dynamic;
 23using System.Dynamic.Utils;
 24#else
 25using Microsoft.Scripting;
 26using Microsoft.Scripting.Utils;
 27#endif
 28using System.Globalization;
 29#if CODEPLEX_40
 30using System.Linq.Expressions;
 31#else
 32using Microsoft.Linq.Expressions;
 33#endif
 34using System.Reflection;
 35
 36#if CODEPLEX_40
 37namespace System.Runtime.CompilerServices {
 38#else
 39namespace Microsoft.Runtime.CompilerServices {
 40#endif
 41    /// <summary>
 42    /// This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
 43    /// Represents a runtime binding at a call site.
 44    /// </summary>
 45    /// <typeparam name="T">The delegate type.</typeparam>
 46    internal sealed class CallSiteRule<T> where T : class {
 47
 48        internal static readonly ReadOnlyCollection<ParameterExpression> Parameters;
 49        internal static readonly LabelTarget ReturnLabel;
 50
 51        // cctor will be lazily executed when a given T is first referenced
 52        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
 53        static CallSiteRule() {
 54            Type target = typeof(T);
 55            if (!typeof(Delegate).IsAssignableFrom(target)) {
 56                throw Error.TypeParameterIsNotDelegate(target);
 57            }
 58
 59            MethodInfo invoke = target.GetMethod("Invoke");
 60            ParameterInfo[] pis = invoke.GetParametersCached();
 61            if (pis[0].ParameterType != typeof(CallSite)) {
 62                throw Error.FirstArgumentMustBeCallSite();
 63            }
 64
 65            var @params = new ParameterExpression[pis.Length - 1];
 66            for (int i = 0; i < @params.Length; i++) {
 67                @params[i] = Expression.Parameter(pis[i + 1].ParameterType, "$arg" + i);
 68            }
 69
 70            Parameters = new TrueReadOnlyCollection<ParameterExpression>(@params);
 71            ReturnLabel = Expression.Label(invoke.GetReturnType());
 72        }
 73
 74        /// <summary>
 75        /// The rule set that includes only this rule.
 76        /// </summary>
 77        internal readonly T Target;
 78
 79        /// <summary>
 80        /// The binding expression tree
 81        /// </summary>
 82        private readonly Expression _binding;
 83
 84        /// <summary>
 85        /// Template data - null for methods which aren't templated.  Non-null for methods which
 86        /// have been templated.  The same template data is shared across all templated rules with
 87        /// the same target method.
 88        /// </summary>
 89        private readonly TemplateData<T> _template;
 90
 91        internal CallSiteRule(Expression binding, T target) {
 92            _binding = binding;
 93            Target = target;
 94        }
 95
 96        internal CallSiteRule(Expression binding, T target, TemplateData<T> template) {
 97            _binding = binding;
 98            _template = template;
 99            Target = target;
100        }
101
102        /// <summary>
103        /// The expression representing the bound operation
104        /// </summary>
105        internal Expression Binding {
106            get { return _binding; }
107        }
108
109        internal TemplateData<T> Template {
110            get {
111                return _template;
112            }
113        }
114
115        /// <summary>
116        /// Gets the method which is used for templating. If the rule is
117        /// not templated then this is a nop (and returns null for the getter).
118        /// </summary>
119        internal Func<Object[], T> TemplateFunction {
120            get {
121                if (_template != null) {
122                    return _template.TemplateFunction;
123                }
124                return null;
125            }
126        }
127
128        internal Set<int> TemplatedConsts {
129            get {
130                if (_template != null) {
131                    return _template.TemplatedConstants;
132                }
133                return null;
134            }
135        }
136
137
138#if MICROSOFT_SCRIPTING_CORE
139        /// <summary>
140        /// Returns a string representation of the <see cref="CallSiteRule{T}"/>.
141        /// </summary>
142        public string Dump {
143            get {
144                using (System.IO.StringWriter writer = new System.IO.StringWriter(CultureInfo.CurrentCulture)) {
145                    ExpressionWriter.Dump(_binding, "Rule", writer);
146                    return writer.ToString();
147                }
148            }
149        }
150#endif
151    }
152
153    /// <summary>
154    /// Data used for tracking templating information in a rule.
155    /// </summary>
156    internal class TemplateData<T> where T : class {
157        private readonly Func<Object[], T> _templateFunction;
158        private readonly Set<int> _templatedConstants;
159
160        internal TemplateData(Func<Object[], T> templateFunction, Set<int> templatedConstants) {
161            _templatedConstants = templatedConstants;
162            _templateFunction = templateFunction;
163        }
164
165        /// <summary>
166        /// Function that can produce concrete lambdas when given list of constant values.
167        /// </summary>
168        internal Func<Object[], T> TemplateFunction {
169            get {
170                return _templateFunction;
171            }
172        }
173
174        /// <summary>
175        /// Specifies which constants are templated by their positions.
176        /// The numbering is assumed as in traversal by ExpressionVisitor.
177        /// We use position as constant identity because it is stable 
178        /// even in trees that contain node junctions.
179        /// </summary>
180        internal Set<int> TemplatedConstants {
181            get {
182                return _templatedConstants;
183            }
184        }
185    }
186}