1<#@ template debug="false" hostspecific="false" language="C#" #> 2<#@ assembly name="System.Core" #> 3<#@ import namespace="System.Linq" #> 4<#@ import namespace="System.Text" #> 5<#@ import namespace="System.Collections.Generic" #> 6<#@ output extension=".cs" #> 7// Licensed to the .NET Foundation under one or more agreements. 8// The .NET Foundation licenses this file to you under the MIT license. 9// See the LICENSE file in the project root for more information. 10 11using System.Runtime.CompilerServices; 12 13namespace System.Dynamic 14{ 15 internal static partial class UpdateDelegates 16 { 17#if FEATURE_COMPILE 18<# 19for (int i = 1; i <= 10; i++) 20{ 21 string genericParameters = string.Join(", ", Enumerable.Range(0, i).Select(j => "T" + j).Concat(new[] { "TRet" })); 22 string parameters = string.Join(", ", new[] { "CallSite site" }.Concat(Enumerable.Range(0, i).Select(j => "T" + j + " arg" + j))); 23 string ruleInvocationArguments = string.Join(", ", new[] { "site" }.Concat(Enumerable.Range(0, i).Select(j => "arg" + j))); 24 string argsArray = i == 0 ? "Array.Empty<object>()" : "new object[] { " + string.Join(", ", Enumerable.Range(0, i).Select(j => "arg" + j)) + " }"; 25#> 26 [Obsolete("pregenerated CallSite<T>.Update delegate", error: true)] 27 internal static TRet UpdateAndExecute<#=i#><<#=genericParameters#>>(<#=parameters#>) 28 { 29 // 30 // Declare the locals here upfront. It actually saves JIT stack space. 31 // 32 var @this = (CallSite<Func<CallSite, <#=genericParameters#>>>)site; 33 Func<CallSite, <#=genericParameters#>>[] applicable; 34 Func<CallSite, <#=genericParameters#>> rule, originalRule = @this.Target; 35 TRet result; 36 37 38 // 39 // Create matchmaker and its site. We'll need them regardless. 40 // 41 site = CallSiteOps.CreateMatchmaker(@this); 42 43 // 44 // Level 1 cache lookup 45 // 46 if ((applicable = CallSiteOps.GetRules(@this)) != null) 47 { 48 for (int i = 0; i < applicable.Length; i++) 49 { 50 rule = applicable[i]; 51 52 // 53 // Execute the rule 54 // 55 56 // if we've already tried it skip it... 57 if ((object)rule != (object)originalRule) 58 { 59 @this.Target = rule; 60 result = rule(<#=ruleInvocationArguments#>); 61 62 if (CallSiteOps.GetMatch(site)) 63 { 64 CallSiteOps.UpdateRules(@this, i); 65 return result; 66 } 67 68 // Rule didn't match, try the next one 69 CallSiteOps.ClearMatch(site); 70 } 71 } 72 } 73 74 // 75 // Level 2 cache lookup 76 // 77 78 // 79 // Any applicable rules in level 2 cache? 80 // 81 82 var cache = CallSiteOps.GetRuleCache(@this); 83 84 applicable = cache.GetRules(); 85 for (int i = 0; i < applicable.Length; i++) 86 { 87 rule = applicable[i]; 88 89 // 90 // Execute the rule 91 // 92 @this.Target = rule; 93 94 try 95 { 96 result = rule(<#=ruleInvocationArguments#>); 97 if (CallSiteOps.GetMatch(site)) 98 { 99 return result; 100 } 101 } 102 finally 103 { 104 if (CallSiteOps.GetMatch(site)) 105 { 106 // 107 // Rule worked. Add it to level 1 cache 108 // 109 CallSiteOps.AddRule(@this, rule); 110 // and then move it to the front of the L2 cache 111 CallSiteOps.MoveRule(cache, rule, i); 112 } 113 } 114 115 // Rule didn't match, try the next one 116 CallSiteOps.ClearMatch(site); 117 } 118 119 // 120 // Miss on Level 0, 1 and 2 caches. Create new rule 121 // 122 123 rule = null; 124 var args = <#=argsArray#>; 125 126 for (; ; ) 127 { 128 @this.Target = originalRule; 129 rule = @this.Target = @this.Binder.BindCore(@this, args); 130 131 // 132 // Execute the rule on the matchmaker site 133 // 134 135 try 136 { 137 result = rule(<#=ruleInvocationArguments#>); 138 if (CallSiteOps.GetMatch(site)) 139 { 140 return result; 141 } 142 } 143 finally 144 { 145 if (CallSiteOps.GetMatch(site)) 146 { 147 // 148 // The rule worked. Add it to level 1 cache. 149 // 150 CallSiteOps.AddRule(@this, rule); 151 } 152 } 153 154 // Rule we got back didn't work, try another one 155 CallSiteOps.ClearMatch(site); 156 } 157 } 158 159 [Obsolete("pregenerated CallSite<T>.Update delegate", error: true)] 160 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters")] 161 internal static TRet NoMatch<#=i#><<#=genericParameters#>>(<#=parameters#>) 162 { 163 site._match = false; 164 return default(TRet); 165 } 166 167 168 169<# 170} 171#> 172<# 173for (int i = 1; i <= 10; i++) 174{ 175 string genericParameters = string.Join(", ", Enumerable.Range(0, i).Select(j => "T" + j)); 176 string parameters = string.Join(", ", new[] { "CallSite site" }.Concat(Enumerable.Range(0, i).Select(j => "T" + j + " arg" + j))); 177 string ruleInvocationArguments = string.Join(", ", new[] { "site" }.Concat(Enumerable.Range(0, i).Select(j => "arg" + j))); 178 string argsArray = i == 0 ? "Array.Empty<object>()" : "new object[] { " + string.Join(", ", Enumerable.Range(0, i).Select(j => "arg" + j)) + " }"; 179#> 180 [Obsolete("pregenerated CallSite<T>.Update delegate", error: true)] 181 internal static void UpdateAndExecuteVoid<#=i#><<#=genericParameters#>>(<#=parameters#>) 182 { 183 // 184 // Declare the locals here upfront. It actually saves JIT stack space. 185 // 186 var @this = (CallSite<Action<CallSite, <#=genericParameters#>>>)site; 187 Action<CallSite, <#=genericParameters#>>[] applicable; 188 Action<CallSite, <#=genericParameters#>> rule, originalRule = @this.Target; 189 190 191 // 192 // Create matchmaker and its site. We'll need them regardless. 193 // 194 site = CallSiteOps.CreateMatchmaker(@this); 195 196 // 197 // Level 1 cache lookup 198 // 199 if ((applicable = CallSiteOps.GetRules(@this)) != null) 200 { 201 for (int i = 0; i < applicable.Length; i++) 202 { 203 rule = applicable[i]; 204 205 // 206 // Execute the rule 207 // 208 209 // if we've already tried it skip it... 210 if ((object)rule != (object)originalRule) 211 { 212 @this.Target = rule; 213 rule(<#=ruleInvocationArguments#>); 214 215 if (CallSiteOps.GetMatch(site)) 216 { 217 CallSiteOps.UpdateRules(@this, i); 218 return; 219 } 220 221 // Rule didn't match, try the next one 222 CallSiteOps.ClearMatch(site); 223 } 224 } 225 } 226 227 // 228 // Level 2 cache lookup 229 // 230 231 // 232 // Any applicable rules in level 2 cache? 233 // 234 235 var cache = CallSiteOps.GetRuleCache(@this); 236 237 applicable = cache.GetRules(); 238 for (int i = 0; i < applicable.Length; i++) 239 { 240 rule = applicable[i]; 241 242 // 243 // Execute the rule 244 // 245 @this.Target = rule; 246 247 try 248 { 249 rule(<#=ruleInvocationArguments#>); 250 if (CallSiteOps.GetMatch(site)) 251 { 252 return; 253 } 254 } 255 finally 256 { 257 if (CallSiteOps.GetMatch(site)) 258 { 259 // 260 // Rule worked. Add it to level 1 cache 261 // 262 CallSiteOps.AddRule(@this, rule); 263 // and then move it to the front of the L2 cache 264 CallSiteOps.MoveRule(cache, rule, i); 265 } 266 } 267 268 // Rule didn't match, try the next one 269 CallSiteOps.ClearMatch(site); 270 } 271 272 // 273 // Miss on Level 0, 1 and 2 caches. Create new rule 274 // 275 276 rule = null; 277 var args = <#=argsArray#>; 278 279 for (; ; ) 280 { 281 @this.Target = originalRule; 282 rule = @this.Target = @this.Binder.BindCore(@this, args); 283 284 // 285 // Execute the rule on the matchmaker site 286 // 287 288 try 289 { 290 rule(<#=ruleInvocationArguments#>); 291 if (CallSiteOps.GetMatch(site)) 292 { 293 return; 294 } 295 } 296 finally 297 { 298 if (CallSiteOps.GetMatch(site)) 299 { 300 // 301 // The rule worked. Add it to level 1 cache. 302 // 303 CallSiteOps.AddRule(@this, rule); 304 } 305 } 306 307 // Rule we got back didn't work, try another one 308 CallSiteOps.ClearMatch(site); 309 } 310 } 311 312 [Obsolete("pregenerated CallSite<T>.Update delegate", error: true)] 313 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters")] 314 internal static void NoMatchVoid<#=i#><<#=genericParameters#>>(<#=parameters#>) 315 { 316 site._match = false; 317 return; 318 } 319<# 320 if (i != 10) 321 { 322#> 323 324 325 326<# 327 } 328} 329#> 330#endif 331 } 332} 333