PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

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