PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/mcs/class/dlr/Runtime/Microsoft.Scripting.Core/Compiler/DelegateHelpers.Generated.cs

https://github.com/skolima/mono
C# | 293 lines | 183 code | 49 blank | 61 comment | 29 complexity | 5cf91570665f955691e305e4689b295a MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. 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 Apache License, Version 2.0, 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 Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Collections.ObjectModel;
  18. using System.Diagnostics;
  19. using System.Dynamic;
  20. using System.Dynamic.Utils;
  21. using System.Runtime.CompilerServices;
  22. #if !FEATURE_CORE_DLR
  23. namespace Microsoft.Scripting.Ast.Compiler {
  24. using Microsoft.Scripting.Utils;
  25. #else
  26. namespace System.Linq.Expressions.Compiler {
  27. #endif
  28. internal static partial class DelegateHelpers {
  29. private static TypeInfo _DelegateCache = new TypeInfo();
  30. #region Generated Maximum Delegate Arity
  31. // *** BEGIN GENERATED CODE ***
  32. // generated by function: gen_max_delegate_arity from: generate_dynsites.py
  33. private const int MaximumArity = 17;
  34. // *** END GENERATED CODE ***
  35. #endregion
  36. internal class TypeInfo {
  37. public Type DelegateType;
  38. public Dictionary<Type, TypeInfo> TypeChain;
  39. public Type MakeDelegateType(Type retType, params Expression[] args) {
  40. return MakeDelegateType(retType, (IList<Expression>)args);
  41. }
  42. public Type MakeDelegateType(Type retType, IList<Expression> args) {
  43. // nope, go ahead and create it and spend the
  44. // cost of creating the array.
  45. Type[] paramTypes = new Type[args.Count + 2];
  46. paramTypes[0] = typeof(CallSite);
  47. paramTypes[paramTypes.Length - 1] = retType;
  48. for (int i = 0; i < args.Count; i++) {
  49. paramTypes[i + 1] = args[i].Type;
  50. }
  51. return DelegateType = MakeNewDelegate(paramTypes);
  52. }
  53. }
  54. /// <summary>
  55. /// Finds a delegate type using the types in the array.
  56. /// We use the cache to avoid copying the array, and to cache the
  57. /// created delegate type
  58. /// </summary>
  59. internal static Type MakeDelegateType(Type[] types) {
  60. lock (_DelegateCache) {
  61. TypeInfo curTypeInfo = _DelegateCache;
  62. // arguments & return type
  63. for (int i = 0; i < types.Length; i++) {
  64. curTypeInfo = NextTypeInfo(types[i], curTypeInfo);
  65. }
  66. // see if we have the delegate already
  67. if (curTypeInfo.DelegateType == null) {
  68. // clone because MakeCustomDelegate can hold onto the array.
  69. curTypeInfo.DelegateType = MakeNewDelegate((Type[])types.Clone());
  70. }
  71. return curTypeInfo.DelegateType;
  72. }
  73. }
  74. /// <summary>
  75. /// Finds a delegate type for a CallSite using the types in the ReadOnlyCollection of Expression.
  76. ///
  77. /// We take the readonly collection of Expression explicitly to avoid allocating memory (an array
  78. /// of types) on lookup of delegate types.
  79. /// </summary>
  80. internal static Type MakeCallSiteDelegate(ReadOnlyCollection<Expression> types, Type returnType) {
  81. lock (_DelegateCache) {
  82. TypeInfo curTypeInfo = _DelegateCache;
  83. // CallSite
  84. curTypeInfo = NextTypeInfo(typeof(CallSite), curTypeInfo);
  85. // arguments
  86. for (int i = 0; i < types.Count; i++) {
  87. curTypeInfo = NextTypeInfo(types[i].Type, curTypeInfo);
  88. }
  89. // return type
  90. curTypeInfo = NextTypeInfo(returnType, curTypeInfo);
  91. // see if we have the delegate already
  92. if (curTypeInfo.DelegateType == null) {
  93. curTypeInfo.MakeDelegateType(returnType, types);
  94. }
  95. return curTypeInfo.DelegateType;
  96. }
  97. }
  98. /// <summary>
  99. /// Finds a delegate type for a CallSite using the MetaObject array.
  100. ///
  101. /// We take the array of MetaObject explicitly to avoid allocating memory (an array of types) on
  102. /// lookup of delegate types.
  103. /// </summary>
  104. internal static Type MakeDeferredSiteDelegate(DynamicMetaObject[] args, Type returnType) {
  105. lock (_DelegateCache) {
  106. TypeInfo curTypeInfo = _DelegateCache;
  107. // CallSite
  108. curTypeInfo = NextTypeInfo(typeof(CallSite), curTypeInfo);
  109. // arguments
  110. for (int i = 0; i < args.Length; i++) {
  111. DynamicMetaObject mo = args[i];
  112. Type paramType = mo.Expression.Type;
  113. if (IsByRef(mo)) {
  114. paramType = paramType.MakeByRefType();
  115. }
  116. curTypeInfo = NextTypeInfo(paramType, curTypeInfo);
  117. }
  118. // return type
  119. curTypeInfo = NextTypeInfo(returnType, curTypeInfo);
  120. // see if we have the delegate already
  121. if (curTypeInfo.DelegateType == null) {
  122. // nope, go ahead and create it and spend the
  123. // cost of creating the array.
  124. Type[] paramTypes = new Type[args.Length + 2];
  125. paramTypes[0] = typeof(CallSite);
  126. paramTypes[paramTypes.Length - 1] = returnType;
  127. for (int i = 0; i < args.Length; i++) {
  128. DynamicMetaObject mo = args[i];
  129. Type paramType = mo.Expression.Type;
  130. if (IsByRef(mo)) {
  131. paramType = paramType.MakeByRefType();
  132. }
  133. paramTypes[i + 1] = paramType;
  134. }
  135. curTypeInfo.DelegateType = MakeNewDelegate(paramTypes);
  136. }
  137. return curTypeInfo.DelegateType;
  138. }
  139. }
  140. private static bool IsByRef(DynamicMetaObject mo) {
  141. ParameterExpression pe = mo.Expression as ParameterExpression;
  142. return pe != null && pe.IsByRef;
  143. }
  144. internal static TypeInfo NextTypeInfo(Type initialArg) {
  145. lock (_DelegateCache) {
  146. return NextTypeInfo(initialArg, _DelegateCache);
  147. }
  148. }
  149. internal static TypeInfo GetNextTypeInfo(Type initialArg, TypeInfo curTypeInfo) {
  150. lock (_DelegateCache) {
  151. return NextTypeInfo(initialArg, curTypeInfo);
  152. }
  153. }
  154. private static TypeInfo NextTypeInfo(Type initialArg, TypeInfo curTypeInfo) {
  155. Type lookingUp = initialArg;
  156. TypeInfo nextTypeInfo;
  157. if (curTypeInfo.TypeChain == null) {
  158. curTypeInfo.TypeChain = new Dictionary<Type, TypeInfo>();
  159. }
  160. if (!curTypeInfo.TypeChain.TryGetValue(lookingUp, out nextTypeInfo)) {
  161. nextTypeInfo = new TypeInfo();
  162. if (TypeUtils.CanCache(lookingUp)) {
  163. curTypeInfo.TypeChain[lookingUp] = nextTypeInfo;
  164. }
  165. }
  166. return nextTypeInfo;
  167. }
  168. /// <summary>
  169. /// Creates a new delegate, or uses a func/action
  170. /// Note: this method does not cache
  171. /// </summary>
  172. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
  173. private static Type MakeNewDelegate(Type[] types) {
  174. Debug.Assert(types != null && types.Length > 0);
  175. // Can only used predefined delegates if we have no byref types and
  176. // the arity is small enough to fit in Func<...> or Action<...>
  177. if (types.Length > MaximumArity || types.Any(t => t.IsByRef)) {
  178. return MakeNewCustomDelegate(types);
  179. }
  180. Type result;
  181. if (types[types.Length - 1] == typeof(void)) {
  182. result = GetActionType(types.RemoveLast());
  183. } else {
  184. result = GetFuncType(types);
  185. }
  186. Debug.Assert(result != null);
  187. return result;
  188. }
  189. internal static Type GetFuncType(Type[] types) {
  190. switch (types.Length) {
  191. #region Generated Delegate Func Types
  192. // *** BEGIN GENERATED CODE ***
  193. // generated by function: gen_delegate_func from: generate_dynsites.py
  194. case 1: return typeof(Func<>).MakeGenericType(types);
  195. case 2: return typeof(Func<,>).MakeGenericType(types);
  196. case 3: return typeof(Func<,,>).MakeGenericType(types);
  197. case 4: return typeof(Func<,,,>).MakeGenericType(types);
  198. case 5: return typeof(Func<,,,,>).MakeGenericType(types);
  199. case 6: return typeof(Func<,,,,,>).MakeGenericType(types);
  200. case 7: return typeof(Func<,,,,,,>).MakeGenericType(types);
  201. case 8: return typeof(Func<,,,,,,,>).MakeGenericType(types);
  202. case 9: return typeof(Func<,,,,,,,,>).MakeGenericType(types);
  203. case 10: return typeof(Func<,,,,,,,,,>).MakeGenericType(types);
  204. case 11: return typeof(Func<,,,,,,,,,,>).MakeGenericType(types);
  205. case 12: return typeof(Func<,,,,,,,,,,,>).MakeGenericType(types);
  206. case 13: return typeof(Func<,,,,,,,,,,,,>).MakeGenericType(types);
  207. case 14: return typeof(Func<,,,,,,,,,,,,,>).MakeGenericType(types);
  208. case 15: return typeof(Func<,,,,,,,,,,,,,,>).MakeGenericType(types);
  209. case 16: return typeof(Func<,,,,,,,,,,,,,,,>).MakeGenericType(types);
  210. case 17: return typeof(Func<,,,,,,,,,,,,,,,,>).MakeGenericType(types);
  211. // *** END GENERATED CODE ***
  212. #endregion
  213. default: return null;
  214. }
  215. }
  216. internal static Type GetActionType(Type[] types) {
  217. switch (types.Length) {
  218. case 0: return typeof(Action);
  219. #region Generated Delegate Action Types
  220. // *** BEGIN GENERATED CODE ***
  221. // generated by function: gen_delegate_action from: generate_dynsites.py
  222. case 1: return typeof(Action<>).MakeGenericType(types);
  223. case 2: return typeof(Action<,>).MakeGenericType(types);
  224. case 3: return typeof(Action<,,>).MakeGenericType(types);
  225. case 4: return typeof(Action<,,,>).MakeGenericType(types);
  226. case 5: return typeof(Action<,,,,>).MakeGenericType(types);
  227. case 6: return typeof(Action<,,,,,>).MakeGenericType(types);
  228. case 7: return typeof(Action<,,,,,,>).MakeGenericType(types);
  229. case 8: return typeof(Action<,,,,,,,>).MakeGenericType(types);
  230. case 9: return typeof(Action<,,,,,,,,>).MakeGenericType(types);
  231. case 10: return typeof(Action<,,,,,,,,,>).MakeGenericType(types);
  232. case 11: return typeof(Action<,,,,,,,,,,>).MakeGenericType(types);
  233. case 12: return typeof(Action<,,,,,,,,,,,>).MakeGenericType(types);
  234. case 13: return typeof(Action<,,,,,,,,,,,,>).MakeGenericType(types);
  235. case 14: return typeof(Action<,,,,,,,,,,,,,>).MakeGenericType(types);
  236. case 15: return typeof(Action<,,,,,,,,,,,,,,>).MakeGenericType(types);
  237. case 16: return typeof(Action<,,,,,,,,,,,,,,,>).MakeGenericType(types);
  238. // *** END GENERATED CODE ***
  239. #endregion
  240. default: return null;
  241. }
  242. }
  243. }
  244. }