mscorlib(4.0.0.0) API with additions
CallSiteBinder.cs
3 using System.Dynamic.Utils;
5 using System.Reflection;
6 using System.Threading;
7 
9 {
11  [global::__DynamicallyInvokable]
12  public abstract class CallSiteBinder
13  {
14  private sealed class LambdaSignature<T> where T : class
15  {
16  internal static readonly LambdaSignature<T> Instance = new LambdaSignature<T>();
17 
18  internal readonly ReadOnlyCollection<ParameterExpression> Parameters;
19 
20  internal readonly LabelTarget ReturnLabel;
21 
22  private LambdaSignature()
23  {
24  Type typeFromHandle = typeof(T);
25  if (!typeFromHandle.IsSubclassOf(typeof(MulticastDelegate)))
26  {
27  throw Error.TypeParameterIsNotDelegate(typeFromHandle);
28  }
29  MethodInfo method = typeFromHandle.GetMethod("Invoke");
30  ParameterInfo[] parametersCached = method.GetParametersCached();
31  if (parametersCached[0].ParameterType != typeof(CallSite))
32  {
33  throw Error.FirstArgumentMustBeCallSite();
34  }
35  ParameterExpression[] array = new ParameterExpression[parametersCached.Length - 1];
36  for (int i = 0; i < array.Length; i++)
37  {
38  array[i] = Expression.Parameter(parametersCached[i + 1].ParameterType, "$arg" + i);
39  }
40  Parameters = new TrueReadOnlyCollection<ParameterExpression>(array);
41  ReturnLabel = Expression.Label(method.GetReturnType());
42  }
43  }
44 
45  private static readonly LabelTarget _updateLabel = Expression.Label("CallSiteBinder.UpdateLabel");
46 
47  internal Dictionary<Type, object> Cache;
48 
51  [global::__DynamicallyInvokable]
52  public static LabelTarget UpdateLabel
53  {
54  [global::__DynamicallyInvokable]
55  get
56  {
57  return _updateLabel;
58  }
59  }
60 
62  [global::__DynamicallyInvokable]
63  protected CallSiteBinder()
64  {
65  }
66 
72  [global::__DynamicallyInvokable]
73  public abstract Expression Bind(object[] args, ReadOnlyCollection<ParameterExpression> parameters, LabelTarget returnLabel);
74 
80  [global::__DynamicallyInvokable]
81  public virtual T BindDelegate<T>(CallSite<T> site, object[] args) where T : class
82  {
83  return null;
84  }
85 
86  internal T BindCore<T>(CallSite<T> site, object[] args) where T : class
87  {
88  T val = BindDelegate(site, args);
89  if (val != null)
90  {
91  return val;
92  }
93  LambdaSignature<T> instance = LambdaSignature<T>.Instance;
94  Expression expression = Bind(args, instance.Parameters, instance.ReturnLabel);
95  if (expression == null)
96  {
97  throw Error.NoOrInvalidRuleProduced();
98  }
100  {
101  throw Error.HomogenousAppDomainRequired();
102  }
103  Expression<T> expression2 = Stitch(expression, instance);
104  T val2 = expression2.Compile();
105  CacheTarget(val2);
106  return val2;
107  }
108 
112  [global::__DynamicallyInvokable]
113  protected void CacheTarget<T>(T target) where T : class
114  {
115  GetRuleCache<T>().AddRule(target);
116  }
117 
118  private static Expression<T> Stitch<T>(Expression binding, LambdaSignature<T> signature) where T : class
119  {
120  Type typeFromHandle = typeof(CallSite<T>);
122  readOnlyCollectionBuilder.Add(binding);
123  ParameterExpression parameterExpression = Expression.Parameter(typeof(CallSite), "$site");
124  ParameterExpression[] array = signature.Parameters.AddFirst(parameterExpression);
125  Expression item = Expression.Label(UpdateLabel);
126  readOnlyCollectionBuilder.Add(item);
127  readOnlyCollectionBuilder.Add(Expression.Label(signature.ReturnLabel, Expression.Condition(Expression.Call(typeof(CallSiteOps).GetMethod("SetNotMatched"), array.First()), Expression.Default(signature.ReturnLabel.Type), Expression.Invoke(Expression.Property(Expression.Convert(parameterExpression, typeFromHandle), typeof(CallSite<T>).GetProperty("Update")), new TrueReadOnlyCollection<Expression>(array)))));
128  return new Expression<T>(Expression.Block(readOnlyCollectionBuilder), "CallSite.Target", tailCall: true, new TrueReadOnlyCollection<ParameterExpression>(array));
129  }
130 
131  internal RuleCache<T> GetRuleCache<T>() where T : class
132  {
133  if (Cache == null)
134  {
135  Interlocked.CompareExchange(ref Cache, new Dictionary<Type, object>(), null);
136  }
137  Dictionary<Type, object> cache = Cache;
138  object value;
139  lock (cache)
140  {
141  if (!cache.TryGetValue(typeof(T), out value))
142  {
143  value = (cache[typeof(T)] = new RuleCache<T>());
144  }
145  }
146  return value as RuleCache<T>;
147  }
148  }
149 }
Discovers the attributes of a parameter and provides access to parameter metadata.
Discovers the attributes of a method and provides access to method metadata.
Definition: MethodInfo.cs:13
virtual T BindDelegate< T >(CallSite< T > site, object[] args)
Provides low-level runtime binding support. Classes can override this and provide a direct delegate f...
Represents a multicast delegate; that is, a delegate that can have more than one element in its invoc...
CallSiteBinder()
Initializes a new instance of the T:System.Runtime.CompilerServices.CallSiteBinder class.
Definition: __Canon.cs:3
A dynamic call site base class. This type is used as a parameter type to the dynamic site targets.
Definition: CallSite.cs:13
Used to represent the target of a T:System.Linq.Expressions.GotoExpression.
Definition: LabelTarget.cs:5
static AppDomain CurrentDomain
Gets the current application domain for the current T:System.Threading.Thread.
Definition: AppDomain.cs:274
bool IsHomogenous
Gets a value that indicates whether the current application domain has a set of permissions that is g...
Definition: AppDomain.cs:468
Represents an application domain, which is an isolated environment where applications execute....
Definition: AppDomain.cs:33
virtual bool IsSubclassOf(Type c)
Determines whether the current T:System.Type derives from the specified T:System.Type.
Definition: Type.cs:2664
static LabelTarget UpdateLabel
Gets a label that can be used to cause the binding to be updated. It indicates that the expression's ...
abstract Expression Bind(object[] args, ReadOnlyCollection< ParameterExpression > parameters, LabelTarget returnLabel)
Performs the runtime binding of the dynamic operation on a set of arguments.
Provides the base class from which the classes that represent expression tree nodes are derived....
Definition: Expression.cs:17
static int CompareExchange(ref int location1, int value, int comparand)
Compares two 32-bit signed integers for equality and, if they are equal, replaces the first value.
Represents type declarations: class types, interface types, array types, value types,...
Definition: Type.cs:18
Creates and caches binding rules.
Definition: CallSiteOps.cs:10
Represents a named parameter expression.
MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
Searches for the specified method whose parameters match the specified argument types and modifiers,...
Definition: Type.cs:1488
void Add(T item)
Adds an item to the T:System.Runtime.CompilerServices.ReadOnlyCollectionBuilder`1.
Represents a collection of keys and values.To browse the .NET Framework source code for this type,...
Definition: Dictionary.cs:17
Class responsible for runtime binding of the dynamic operations on the dynamic call site.
void CacheTarget< T >(T target)
Adds a target to the cache of known targets. The cached targets will be scanned before calling BindDe...
Specifies that instance members are to be included in the search.
bool TryGetValue(TKey key, out TValue value)
Gets the value associated with the specified key.
Definition: Dictionary.cs:1624
Provides atomic operations for variables that are shared by multiple threads.
Definition: Interlocked.cs:10