12 [global::__DynamicallyInvokable]
15 private static volatile CacheDict<Type, Func<CallSiteBinder, CallSite>> _SiteCtors;
23 [global::__DynamicallyInvokable]
26 [global::__DynamicallyInvokable]
42 [global::__DynamicallyInvokable]
45 ContractUtils.RequiresNotNull(delegateType,
"delegateType");
46 ContractUtils.RequiresNotNull(binder,
"binder");
49 throw Error.TypeMustBeDerivedFromSystemDelegate();
51 CacheDict<Type, Func<CallSiteBinder, CallSite>> cacheDict = _SiteCtors;
52 if (cacheDict ==
null)
54 cacheDict = (_SiteCtors =
new CacheDict<Type, Func<CallSiteBinder, CallSite>>(100));
57 if (!cacheDict.TryGetValue(delegateType, out Func<CallSiteBinder, CallSite> value))
59 methodInfo = typeof(
CallSite<>).MakeGenericType(delegateType).GetMethod(
"Create");
60 if (delegateType.CanCache())
62 value = (Func<CallSiteBinder, CallSite>)
Delegate.
CreateDelegate(typeof(Func<CallSiteBinder, CallSite>), methodInfo);
63 cacheDict.Add(delegateType, value);
70 return (
CallSite)methodInfo.Invoke(
null,
new object[1]
78 [global::__DynamicallyInvokable]
82 [global::__DynamicallyInvokable]
87 private static T _CachedUpdate;
89 private static volatile T _CachedNoMatch;
91 private const int MaxRules = 10;
95 [global::__DynamicallyInvokable]
98 [global::__DynamicallyInvokable]
103 return _CachedNoMatch;
105 return _CachedUpdate;
112 Target = GetUpdateDelegate();
120 internal CallSite<T> CreateMatchMaker()
122 return new CallSite<T>();
128 [global::__DynamicallyInvokable]
133 throw Error.TypeMustBeDerivedFromSystemDelegate();
138 private T GetUpdateDelegate()
140 return GetUpdateDelegate(ref _CachedUpdate);
143 private T GetUpdateDelegate(ref T addr)
147 addr = MakeUpdateDelegate();
152 private void ClearRuleCache()
154 base.Binder.GetRuleCache<T>();
165 internal void AddRule(T newRule)
177 if (rules.Length < 9)
179 array =
new T[rules.Length + 1];
180 Array.Copy(rules, 0, array, 1, rules.Length);
185 Array.Copy(rules, 0, array, 1, 9);
191 internal void MoveRule(
int i)
195 rules[i] = rules[i - 1];
196 rules[i - 1] = rules[i - 2];
200 internal T MakeUpdateDelegate()
202 Type typeFromHandle = typeof(T);
203 MethodInfo method = typeFromHandle.GetMethod(
"Invoke");
204 if (typeFromHandle.IsGenericType && IsSimpleSignature(method, out Type[] sig))
210 if (typeFromHandle == DelegateHelpers.GetActionType(sig.AddFirst(typeof(CallSite))))
212 methodInfo = typeof(UpdateDelegates).GetMethod(
"UpdateAndExecuteVoid" + sig.Length,
BindingFlags.Static |
BindingFlags.NonPublic);
213 methodInfo2 = typeof(UpdateDelegates).GetMethod(
"NoMatchVoid" + sig.Length,
BindingFlags.Static |
BindingFlags.NonPublic);
216 else if (typeFromHandle == DelegateHelpers.GetFuncType(sig.AddFirst(typeof(CallSite))))
218 methodInfo = typeof(UpdateDelegates).GetMethod(
"UpdateAndExecute" + (sig.Length - 1),
BindingFlags.Static |
BindingFlags.NonPublic);
219 methodInfo2 = typeof(UpdateDelegates).GetMethod(
"NoMatch" + (sig.Length - 1),
BindingFlags.Static |
BindingFlags.NonPublic);
221 if (methodInfo !=
null)
223 _CachedNoMatch = (
T)(
object)CreateDelegateHelper(typeFromHandle, methodInfo2.
MakeGenericMethod(sig));
224 return (T)(object)CreateDelegateHelper(typeFromHandle, methodInfo.
MakeGenericMethod(sig));
227 _CachedNoMatch = CreateCustomNoMatchDelegate(method);
228 return CreateCustomUpdateDelegate(method);
233 return Delegate.CreateDelegate(delegateType, method);
236 private static bool IsSimpleSignature(
MethodInfo invoke, out Type[] sig)
238 ParameterInfo[] parametersCached = invoke.GetParametersCached();
239 ContractUtils.Requires(parametersCached.Length != 0 && parametersCached[0].
ParameterType == typeof(CallSite),
"T");
240 Type[] array =
new Type[(invoke.
ReturnType != typeof(
void)) ? parametersCached.Length : (parametersCached.Length - 1)];
242 for (
int i = 1; i < parametersCached.Length; i++)
245 if (parameterInfo.IsByRefParameter())
259 private T CreateCustomNoMatchDelegate(
MethodInfo invoke)
265 private T CreateCustomUpdateDelegate(
MethodInfo invoke)
278 list2.
Add(parameterExpression2);
279 list.Add(
Expression.Assign(parameterExpression2,
Expression.Convert(parameterExpression, parameterExpression2.
Type)));
281 list2.
Add(parameterExpression3);
283 list2.
Add(parameterExpression4);
285 list2.
Add(parameterExpression5);
286 list.Add(
Expression.Assign(parameterExpression5,
Expression.Field(parameterExpression2,
"Target")));
288 if (labelTarget.
Type != typeof(
void))
290 list2.
Add(parameterExpression6 =
Expression.Variable(labelTarget.
Type,
"result"));
293 list2.
Add(parameterExpression7);
295 list2.
Add(parameterExpression8);
296 list.Add(
Expression.Assign(parameterExpression,
Expression.Call(typeof(CallSiteOps),
"CreateMatchmaker", typeArguments, parameterExpression2)));
297 Expression test =
Expression.Call(typeof(CallSiteOps).GetMethod(
"GetMatch"), parameterExpression);
298 Expression expression =
Expression.Call(typeof(CallSiteOps).GetMethod(
"ClearMatch"), parameterExpression);
300 Expression arg2 = (!(labelTarget.
Type == typeof(
void))) ?
Expression.Block(
Expression.Assign(parameterExpression6,
Expression.Invoke(parameterExpression4,
new TrueReadOnlyCollection<Expression>(array))),
Expression.IfThen(test,
Expression.Block(arg,
Expression.Return(labelTarget, parameterExpression6)))) :
Expression.Block(
Expression.Invoke(parameterExpression4,
new TrueReadOnlyCollection<Expression>(array)),
Expression.IfThen(test,
Expression.Block(arg,
Expression.Return(labelTarget))));
305 list.Add(
Expression.IfThen(
Expression.NotEqual(
Expression.Assign(parameterExpression3,
Expression.Call(typeof(CallSiteOps),
"GetRules", typeArguments, parameterExpression2)),
Expression.Constant(
null, parameterExpression3.
Type)),
Expression.Block(
Expression.Assign(parameterExpression7,
Expression.ArrayLength(parameterExpression3)),
Expression.Assign(parameterExpression8,
Expression.Constant(0)),
Expression.Loop(
Expression.Block(arg4, arg3,
Expression.IfThen(
Expression.NotEqual(
Expression.Convert(parameterExpression4, typeof(
object)),
Expression.Convert(parameterExpression5, typeof(
object))),
Expression.Block(
Expression.Assign(
Expression.Field(parameterExpression2,
"Target"), parameterExpression4), arg2, expression)), unaryExpression), labelTarget2,
null))));
307 list2.
Add(parameterExpression9);
308 list.Add(
Expression.Assign(parameterExpression9,
Expression.Call(typeof(CallSiteOps),
"GetRuleCache", typeArguments, parameterExpression2)));
309 list.Add(
Expression.Assign(parameterExpression3,
Expression.Call(typeof(CallSiteOps),
"GetCachedRules", typeArguments, parameterExpression9)));
311 TryExpression arg5 =
Expression.TryFinally(arg2,
Expression.IfThen(test,
Expression.Block(
Expression.Call(typeof(CallSiteOps),
"AddRule", typeArguments, parameterExpression2, parameterExpression4),
Expression.Call(typeof(CallSiteOps),
"MoveRule", typeArguments, parameterExpression9, parameterExpression4, parameterExpression8))));
314 list.Add(
Expression.Assign(parameterExpression7,
Expression.ArrayLength(parameterExpression3)));
315 list.Add(
Expression.Loop(
Expression.Block(arg4, arg3, arg5, expression, unaryExpression), labelTarget2,
null));
318 list2.
Add(parameterExpression10);
321 arg3 =
Expression.Assign(
Expression.Field(parameterExpression2,
"Target"),
Expression.Assign(parameterExpression4,
Expression.Call(typeof(CallSiteOps),
"Bind", typeArguments,
Expression.Property(parameterExpression2,
"Binder"), parameterExpression2, parameterExpression10)));
322 arg5 =
Expression.TryFinally(arg2,
Expression.IfThen(test,
Expression.Call(typeof(CallSiteOps),
"AddRule", typeArguments, parameterExpression2, parameterExpression4)));
326 return expression2.Compile();
331 if (TypeUtils.AreReferenceAssignable(type, arg.Type))
Discovers the attributes of a parameter and provides access to parameter metadata.
override Type Type
Gets the static type of the expression that this T:System.Linq.Expressions.Expression represents.
Discovers the attributes of a method and provides access to method metadata.
Type Type
The type of value that is passed when jumping to the label (or T:System.Void if no value should be pa...
Represents a multicast delegate; that is, a delegate that can have more than one element in its invoc...
BindingFlags
Specifies flags that control binding and the way in which the search for members and types is conduct...
virtual Type ReturnType
Gets the return type of this method.
virtual MethodInfo MakeGenericMethod(params Type[] typeArguments)
Substitutes the elements of an array of types for the type parameters of the current generic method d...
A dynamic call site base class. This type is used as a parameter type to the dynamic site targets.
Used to represent the target of a T:System.Linq.Expressions.GotoExpression.
static CallSite< T > Create(CallSiteBinder binder)
Creates an instance of the dynamic call site, initialized with the binder responsible for the runtime...
virtual bool IsSubclassOf(Type c)
Determines whether the current T:System.Type derives from the specified T:System.Type.
void Add(T item)
Adds an object to the end of the T:System.Collections.Generic.List`1.
Provides the base class from which the classes that represent expression tree nodes are derived....
T Update
The update delegate. Called when the dynamic site experiences cache miss.
Represents a delegate, which is a data structure that refers to a static method or to a class instanc...
Represents type declarations: class types, interface types, array types, value types,...
Represents a named parameter expression.
Selects a member from a list of candidates, and performs type conversion from actual argument type to...
static CallSite Create(Type delegateType, CallSiteBinder binder)
Creates a call site with the given delegate type and binder.
Represents a collection of keys and values.To browse the .NET Framework source code for this type,...
Represents a try/catch/finally/fault block.
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Class responsible for runtime binding of the dynamic operations on the dynamic call site.
Represents an expression that has a unary operator.
virtual Type ParameterType
Gets the Type of this parameter.
Represents a call to either static or an instance method.
Represents an expression that has a conditional operator.
void Clear()
Removes all keys and values from the T:System.Collections.Generic.Dictionary`2.
T Target
The Level 0 cache - a delegate specialized based on the site history.
virtual string Name
Gets the name of the parameter.
static Delegate CreateDelegate(Type type, object target, string method)
Creates a delegate of the specified type that represents the specified instance method to invoke on t...
Attribute can be applied to a delegate.