You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			750 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			750 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| // ==++==
 | |
| // 
 | |
| //   Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| // 
 | |
| // ==--==
 | |
| namespace System
 | |
| {
 | |
|     using System;
 | |
|     using System.Reflection;
 | |
|     using System.Runtime;
 | |
|     using System.Runtime.Serialization;
 | |
|     using System.Diagnostics.Contracts;
 | |
|     using System.Reflection.Emit;
 | |
|     
 | |
|     [Serializable]
 | |
|     [System.Runtime.InteropServices.ComVisible(true)]
 | |
|     public abstract class MulticastDelegate : Delegate
 | |
|     {
 | |
|         // This is set under 3 circumstances
 | |
|         // 1. Multicast delegate
 | |
|         // 2. Secure/Wrapper delegate
 | |
|         // 3. Inner delegate of secure delegate where the secure delegate security context is a collectible method
 | |
|         [System.Security.SecurityCritical]
 | |
|         private Object   _invocationList;
 | |
|         [System.Security.SecurityCritical]
 | |
|         private IntPtr   _invocationCount;
 | |
| 
 | |
|         // This constructor is called from the class generated by the
 | |
|         //    compiler generated code (This must match the constructor
 | |
|         //    in Delegate
 | |
|         protected MulticastDelegate(Object target, String method) : base(target, method)
 | |
|         {
 | |
|         }
 | |
|         
 | |
|         // This constructor is called from a class to generate a 
 | |
|         // delegate based upon a static method name and the Type object
 | |
|         // for the class defining the method.
 | |
|         protected MulticastDelegate(Type target, String method) : base(target, method) 
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         internal bool IsUnmanagedFunctionPtr()
 | |
|         {
 | |
|             return (_invocationCount == (IntPtr)(-1));
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         internal bool InvocationListLogicallyNull()
 | |
|         {
 | |
|             return (_invocationList == null) || (_invocationList is LoaderAllocator) || (_invocationList is DynamicResolver);
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         public override void GetObjectData(SerializationInfo info, StreamingContext context)
 | |
|         {
 | |
|             int targetIndex = 0;
 | |
|             Object[] invocationList = _invocationList as Object[];
 | |
|             if (invocationList == null)
 | |
|             {
 | |
|                 MethodInfo method = Method;
 | |
|                 // A MethodInfo object can be a RuntimeMethodInfo, a RefEmit method (MethodBuilder, etc), or a DynamicMethod
 | |
|                 // One can only create delegates on RuntimeMethodInfo and DynamicMethod.
 | |
|                 // If it is not a RuntimeMethodInfo (must be a DynamicMethod) or if it is an unmanaged function pointer, throw
 | |
|                 if ( !(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr() ) 
 | |
|                     throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
 | |
| 
 | |
|                 // We can't deal with secure delegates either.
 | |
|                 if (!InvocationListLogicallyNull() && !_invocationCount.IsNull() && !_methodPtrAux.IsNull())
 | |
|                     throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
 | |
| 
 | |
|                 DelegateSerializationHolder.GetDelegateSerializationInfo(info,  this.GetType(), Target, method, targetIndex);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 DelegateSerializationHolder.DelegateEntry nextDe = null;
 | |
|                 int invocationCount = (int)_invocationCount;
 | |
|                 for (int i = invocationCount; --i >= 0; )
 | |
|                 {
 | |
|                     MulticastDelegate d = (MulticastDelegate)invocationList[i];
 | |
|                     MethodInfo method = d.Method;
 | |
|                     // If it is not a RuntimeMethodInfo (must be a DynamicMethod) or if it is an unmanaged function pointer, skip
 | |
|                     if ( !(method is RuntimeMethodInfo) || IsUnmanagedFunctionPtr() ) 
 | |
|                         continue;
 | |
| 
 | |
|                     // We can't deal with secure delegates either.
 | |
|                     if (!d.InvocationListLogicallyNull() && !d._invocationCount.IsNull() && !d._methodPtrAux.IsNull())
 | |
|                         continue;
 | |
| 
 | |
|                     DelegateSerializationHolder.DelegateEntry de = DelegateSerializationHolder.GetDelegateSerializationInfo(info, d.GetType(), d.Target, method, targetIndex++);
 | |
|                     if (nextDe != null)
 | |
|                         nextDe.Entry = de;
 | |
|                     
 | |
|                     nextDe = de;
 | |
|                 }
 | |
|                 // if nothing was serialized it is a delegate over a DynamicMethod, so just throw
 | |
|                 if (nextDe == null) 
 | |
|                     throw new SerializationException(Environment.GetResourceString("Serialization_InvalidDelegateType"));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // equals returns true IIF the delegate is not null and has the
 | |
|         //    same target, method and invocation list as this object
 | |
|         [System.Security.SecuritySafeCritical]  // auto-generated
 | |
|         public override sealed bool Equals(Object obj)
 | |
|         {
 | |
|             if (obj == null || !InternalEqualTypes(this, obj))
 | |
|                 return false;      
 | |
|             MulticastDelegate d = obj as MulticastDelegate;
 | |
|             if (d == null)
 | |
|                 return false;
 | |
| 
 | |
|             if (_invocationCount != (IntPtr)0) 
 | |
|             {
 | |
|                 // there are 4 kind of delegate kinds that fall into this bucket
 | |
|                 // 1- Multicast (_invocationList is Object[])
 | |
|                 // 2- Secure/Wrapper (_invocationList is Delegate)
 | |
|                 // 3- Unmanaged FntPtr (_invocationList == null)
 | |
|                 // 4- Open virtual (_invocationCount == MethodDesc of target, _invocationList == null, LoaderAllocator, or DynamicResolver)
 | |
| 
 | |
|                 if (InvocationListLogicallyNull())
 | |
|                 {
 | |
|                     if (IsUnmanagedFunctionPtr())
 | |
|                     {
 | |
|                         if (!d.IsUnmanagedFunctionPtr())
 | |
|                             return false;
 | |
| 
 | |
|                         return CompareUnmanagedFunctionPtrs(this, d);
 | |
|                     }
 | |
| 
 | |
|                     // now we know 'this' is not a special one, so we can work out what the other is
 | |
|                     if ((d._invocationList as Delegate) != null)
 | |
|                         // this is a secure/wrapper delegate so we need to unwrap and check the inner one
 | |
|                         return Equals(d._invocationList);
 | |
|  
 | |
|                     return base.Equals(obj);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if ((_invocationList as Delegate) != null) 
 | |
|                     {
 | |
|                         // this is a secure/wrapper delegate so we need to unwrap and check the inner one
 | |
|                         return _invocationList.Equals(obj); 
 | |
|                     }
 | |
|                     else 
 | |
|                     {
 | |
|                         Contract.Assert((_invocationList as Object[]) != null, "empty invocation list on multicast delegate");
 | |
|                         return InvocationListEquals(d);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // among the several kind of delegates falling into this bucket one has got a non
 | |
|                 // empty _invocationList (open static with special sig)
 | |
|                 // to be equals we need to check that _invocationList matches (both null is fine)
 | |
|                 // and call the base.Equals()
 | |
|                 if (!InvocationListLogicallyNull())
 | |
|                 {
 | |
|                     if (!_invocationList.Equals(d._invocationList)) 
 | |
|                         return false;
 | |
|                     return base.Equals(d);
 | |
|                 }
 | |
|             
 | |
|                 // now we know 'this' is not a special one, so we can work out what the other is
 | |
|                 if ((d._invocationList as Delegate) != null)
 | |
|                     // this is a secure/wrapper delegate so we need to unwrap and check the inner one
 | |
|                     return Equals(d._invocationList);
 | |
| 
 | |
|                 // now we can call on the base
 | |
|                 return base.Equals(d);
 | |
|             }
 | |
|         }
 | |
|         
 | |
|         // Recursive function which will check for equality of the invocation list.
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         private bool InvocationListEquals(MulticastDelegate d)
 | |
|         {
 | |
|             Contract.Assert(d != null && (_invocationList as Object[]) != null, "bogus delegate in multicast list comparison");
 | |
|             Object[] invocationList = _invocationList as Object[];
 | |
|             if (d._invocationCount != _invocationCount)
 | |
|                 return false;
 | |
|             
 | |
|             int invocationCount = (int)_invocationCount;
 | |
|             for (int i = 0; i < invocationCount; i++)
 | |
|             {
 | |
|                 Delegate dd = (Delegate)invocationList[i];
 | |
|                 Object[] dInvocationList = d._invocationList as Object[];
 | |
|                 if (!dd.Equals(dInvocationList[i]))
 | |
|                     return false;
 | |
|             }
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         private bool TrySetSlot(Object[] a, int index, Object o)
 | |
|         {
 | |
|             if (a[index] == null && System.Threading.Interlocked.CompareExchange<Object>(ref a[index], o, null) == null)
 | |
|                 return true;
 | |
|             
 | |
|             // The slot may be already set because we have added and removed the same method before.
 | |
|             // Optimize this case, because it's cheaper than copying the array.
 | |
|             if (a[index] != null)
 | |
|             {
 | |
|                 MulticastDelegate d  = (MulticastDelegate)o;
 | |
|                 MulticastDelegate dd = (MulticastDelegate)a[index];
 | |
|                 
 | |
|                 if (dd._methodPtr    == d._methodPtr &&
 | |
|                     dd._target       == d._target    &&
 | |
|                     dd._methodPtrAux == d._methodPtrAux)
 | |
|                 {
 | |
|                     return true;
 | |
|                 }
 | |
|             }
 | |
|             return false;
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         private MulticastDelegate NewMulticastDelegate(Object[] invocationList, int invocationCount, bool thisIsMultiCastAlready)
 | |
|         {
 | |
|             // First, allocate a new multicast delegate just like this one, i.e. same type as the this object
 | |
|             MulticastDelegate result = (MulticastDelegate)InternalAllocLike(this);
 | |
| 
 | |
|             // Performance optimization - if this already points to a true multicast delegate,
 | |
|             // copy _methodPtr and _methodPtrAux fields rather than calling into the EE to get them
 | |
|             if (thisIsMultiCastAlready)
 | |
|             {
 | |
|                 result._methodPtr    = this._methodPtr;
 | |
|                 result._methodPtrAux = this._methodPtrAux;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 result._methodPtr    = GetMulticastInvoke();
 | |
|                 result._methodPtrAux = GetInvokeMethod();
 | |
|             }
 | |
|             result._target = result;
 | |
|             result._invocationList = invocationList;
 | |
|             result._invocationCount = (IntPtr)invocationCount;
 | |
| 
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         internal MulticastDelegate NewMulticastDelegate(Object[] invocationList, int invocationCount)
 | |
|         {
 | |
|             return NewMulticastDelegate(invocationList, invocationCount, false);
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         internal void StoreDynamicMethod(MethodInfo dynamicMethod) 
 | |
|         {
 | |
|             if (_invocationCount != (IntPtr)0) 
 | |
|             {
 | |
|                 Contract.Assert(!IsUnmanagedFunctionPtr(), "dynamic method and unmanaged fntptr delegate combined");
 | |
|                 // must be a secure/wrapper one, unwrap and save
 | |
|                 MulticastDelegate d = (MulticastDelegate)_invocationList;
 | |
|                 d._methodBase = dynamicMethod;
 | |
| 
 | |
|             }
 | |
|             else 
 | |
|                 _methodBase = dynamicMethod;
 | |
|         }
 | |
| 
 | |
|         // This method will combine this delegate with the passed delegate
 | |
|         //    to form a new delegate.
 | |
|         [System.Security.SecuritySafeCritical]  // auto-generated
 | |
|         protected override sealed Delegate CombineImpl(Delegate follow)
 | |
|         {
 | |
|             if ((Object)follow == null) // cast to object for a more efficient test
 | |
|                 return this;
 | |
| 
 | |
|             // Verify that the types are the same...
 | |
|             if (!InternalEqualTypes(this, follow))
 | |
|                 throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTypeMis"));
 | |
| 
 | |
|             MulticastDelegate dFollow = (MulticastDelegate)follow;
 | |
|             Object[] resultList;
 | |
|             int followCount = 1;
 | |
|             Object[] followList = dFollow._invocationList as Object[];
 | |
|             if (followList != null)
 | |
|                 followCount = (int)dFollow._invocationCount; 
 | |
|             
 | |
|             int resultCount;
 | |
|             Object[] invocationList = _invocationList as Object[];
 | |
|             if (invocationList == null)
 | |
|             {
 | |
|                 resultCount = 1 + followCount;
 | |
|                 resultList = new Object[resultCount];
 | |
|                 resultList[0] = this;
 | |
|                 if (followList == null)
 | |
|                 {
 | |
|                     resultList[1] = dFollow;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     for (int i = 0; i < followCount; i++)
 | |
|                         resultList[1 + i] = followList[i];
 | |
|                 }
 | |
|                 return NewMulticastDelegate(resultList, resultCount);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int invocationCount = (int)_invocationCount;
 | |
|                 resultCount = invocationCount + followCount;
 | |
|                 resultList = null;
 | |
|                 if (resultCount <= invocationList.Length)
 | |
|                 {
 | |
|                     resultList = invocationList;
 | |
|                     if (followList == null)
 | |
|                     {
 | |
|                         if (!TrySetSlot(resultList, invocationCount, dFollow))
 | |
|                             resultList = null;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         for (int i = 0; i < followCount; i++)
 | |
|                         {
 | |
|                             if (!TrySetSlot(resultList, invocationCount + i, followList[i]))
 | |
|                             {
 | |
|                                 resultList = null;
 | |
|                                 break;
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 if (resultList == null)
 | |
|                 {
 | |
|                     int allocCount = invocationList.Length;
 | |
|                     while (allocCount < resultCount)
 | |
|                         allocCount *= 2;
 | |
|                     
 | |
|                     resultList = new Object[allocCount];
 | |
|                     
 | |
|                     for (int i = 0; i < invocationCount; i++)
 | |
|                         resultList[i] = invocationList[i];
 | |
|                     
 | |
|                     if (followList == null)
 | |
|                     {
 | |
|                         resultList[invocationCount] = dFollow;
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         for (int i = 0; i < followCount; i++)
 | |
|                             resultList[invocationCount + i] = followList[i];
 | |
|                     }
 | |
|                 }
 | |
|                 return NewMulticastDelegate(resultList, resultCount, true);
 | |
|             }
 | |
|         }
 | |
|                                        
 | |
|         [System.Security.SecurityCritical]
 | |
|         private Object[] DeleteFromInvocationList(Object[] invocationList, int invocationCount, int deleteIndex, int deleteCount)
 | |
|         {
 | |
|             Object[] thisInvocationList = _invocationList as Object[];
 | |
|             int allocCount = thisInvocationList.Length;
 | |
|             while (allocCount/2 >= invocationCount - deleteCount)
 | |
|                 allocCount /= 2;
 | |
|             
 | |
|             Object[] newInvocationList = new Object[allocCount];
 | |
|             
 | |
|             for (int i = 0; i < deleteIndex; i++)
 | |
|                 newInvocationList[i] = invocationList[i];
 | |
|             
 | |
|             for (int i = deleteIndex + deleteCount; i < invocationCount; i++)
 | |
|                 newInvocationList[i - deleteCount] = invocationList[i];
 | |
|             
 | |
|             return newInvocationList;
 | |
|         }
 | |
| 
 | |
|         private bool EqualInvocationLists(Object[] a, Object[] b, int start, int count)
 | |
|         {
 | |
|             for (int i = 0; i < count; i++)
 | |
|             {
 | |
|                 if (!(a[start + i].Equals(b[i])))
 | |
|                     return false;
 | |
|             }
 | |
|             return true;
 | |
|         }
 | |
| 
 | |
|         // This method currently looks backward on the invocation list
 | |
|         //    for an element that has Delegate based equality with value.  (Doesn't
 | |
|         //    look at the invocation list.)  If this is found we remove it from
 | |
|         //    this list and return a new delegate.  If its not found a copy of the
 | |
|         //    current list is returned.
 | |
|         [System.Security.SecuritySafeCritical]  // auto-generated
 | |
|         protected override sealed Delegate RemoveImpl(Delegate value)
 | |
|         {
 | |
|             // There is a special case were we are removing using a delegate as
 | |
|             //    the value we need to check for this case
 | |
|             //
 | |
|             MulticastDelegate v = value as MulticastDelegate;
 | |
|             
 | |
|             if (v == null) 
 | |
|                 return this;
 | |
|             if (v._invocationList as Object[] == null)
 | |
|             {
 | |
|                 Object[] invocationList = _invocationList as Object[];
 | |
|                 if (invocationList == null)
 | |
|                 {
 | |
|                     // they are both not real Multicast
 | |
|                     if (this.Equals(value))
 | |
|                         return null;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     int invocationCount = (int)_invocationCount;
 | |
|                     for (int i = invocationCount; --i >= 0; )
 | |
|                     {
 | |
|                         if (value.Equals(invocationList[i]))
 | |
|                         {
 | |
|                             if (invocationCount == 2)
 | |
|                             {
 | |
|                                 // Special case - only one value left, either at the beginning or the end
 | |
|                                 return (Delegate)invocationList[1-i];
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 Object[] list = DeleteFromInvocationList(invocationList, invocationCount, i, 1);
 | |
|                                 return NewMulticastDelegate(list, invocationCount-1, true);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 Object[] invocationList = _invocationList as Object[];
 | |
|                 if (invocationList != null) {
 | |
|                     int invocationCount = (int)_invocationCount;
 | |
|                     int vInvocationCount = (int)v._invocationCount;
 | |
|                     for (int i = invocationCount - vInvocationCount; i >= 0; i--)
 | |
|                     {
 | |
|                         if (EqualInvocationLists(invocationList, v._invocationList as Object[], i, vInvocationCount))
 | |
|                         {
 | |
|                             if (invocationCount - vInvocationCount == 0)
 | |
|                             {
 | |
|                                 // Special case - no values left
 | |
|                                 return null;
 | |
|                             }
 | |
|                             else if (invocationCount - vInvocationCount == 1)
 | |
|                             {
 | |
|                                 // Special case - only one value left, either at the beginning or the end
 | |
|                                 return (Delegate)invocationList[i != 0 ? 0 : invocationCount-1];
 | |
|                             }
 | |
|                             else
 | |
|                             {
 | |
|                                 Object[] list = DeleteFromInvocationList(invocationList, invocationCount, i, vInvocationCount);
 | |
|                                 return NewMulticastDelegate(list, invocationCount - vInvocationCount, true);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|    
 | |
|             return this;
 | |
|         }
 | |
| 
 | |
|         // This method returns the Invocation list of this multicast delegate.
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         public override sealed Delegate[] GetInvocationList()
 | |
|         {
 | |
|             Contract.Ensures(Contract.Result<Delegate[]>() != null);
 | |
|             // @
 | |
| 
 | |
| 
 | |
|             Delegate[] del;
 | |
|             Object[] invocationList = _invocationList as Object[];
 | |
|             if (invocationList == null)
 | |
|             {
 | |
|                 del = new Delegate[1];
 | |
|                 del[0] = this;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // Create an array of delegate copies and each
 | |
|                 //    element into the array
 | |
|                 int invocationCount = (int)_invocationCount;
 | |
|                 del = new Delegate[invocationCount];
 | |
|                 
 | |
|                 for (int i = 0; i < invocationCount; i++)
 | |
|                     del[i] = (Delegate)invocationList[i];
 | |
|             }
 | |
|             return del;
 | |
|         }
 | |
| 
 | |
|         public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2)
 | |
|         {
 | |
|             if ((Object)d1 == null)
 | |
|                 return (Object)d2 == null;
 | |
|             
 | |
|             return d1.Equals(d2);
 | |
|         }
 | |
| 
 | |
|         public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2)
 | |
|         {
 | |
|             if ((Object)d1 == null)
 | |
|                 return (Object)d2 != null;
 | |
|             
 | |
|             return !d1.Equals(d2);
 | |
|         }
 | |
|         
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         public override sealed int GetHashCode()
 | |
|         {
 | |
|             if (IsUnmanagedFunctionPtr())
 | |
|                 return ValueType.GetHashCodeOfPtr(_methodPtr) ^ ValueType.GetHashCodeOfPtr(_methodPtrAux);
 | |
| 
 | |
|             Object[] invocationList = _invocationList as Object[];
 | |
|             if (invocationList == null)
 | |
|             {
 | |
|                 return base.GetHashCode();
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 int hash = 0;
 | |
|                 for (int i = 0; i < (int)_invocationCount; i++)
 | |
|                 {
 | |
|                     hash = hash*33 + invocationList[i].GetHashCode();
 | |
|                 }
 | |
|                 
 | |
|                 return hash;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         internal override Object GetTarget()
 | |
|         {
 | |
|             if (_invocationCount != (IntPtr)0) 
 | |
|             {
 | |
|                 // _invocationCount != 0 we are in one of these cases:
 | |
|                 // - Multicast -> return the target of the last delegate in the list
 | |
|                 // - Secure/wrapper delegate -> return the target of the inner delegate
 | |
|                 // - unmanaged function pointer - return null
 | |
|                 // - virtual open delegate - return null
 | |
|                 if (InvocationListLogicallyNull())
 | |
|                 {
 | |
|                     // both open virtual and ftn pointer return null for the target
 | |
|                     return null;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     Object[] invocationList = _invocationList as Object[];
 | |
|                     if (invocationList != null) 
 | |
|                     {
 | |
|                         int invocationCount = (int)_invocationCount;
 | |
|                         return ((Delegate)invocationList[invocationCount - 1]).GetTarget();
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         Delegate receiver = _invocationList as Delegate;
 | |
|                         if (receiver != null) 
 | |
|                             return receiver.GetTarget();
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return base.GetTarget();
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecuritySafeCritical]
 | |
|         protected override MethodInfo GetMethodImpl()
 | |
|         {
 | |
|             if (_invocationCount != (IntPtr)0 && _invocationList != null)
 | |
|             {
 | |
|                 // multicast case
 | |
|                 Object[] invocationList = _invocationList as Object[];
 | |
|                 if (invocationList != null)
 | |
|                 {
 | |
|                     int index = (int)_invocationCount - 1;
 | |
|                     return ((Delegate)invocationList[index]).Method;
 | |
|                 }
 | |
|                 MulticastDelegate innerDelegate = _invocationList as MulticastDelegate;
 | |
|                 if (innerDelegate != null)
 | |
|                 {
 | |
|                     // must be a secure/wrapper delegate
 | |
|                     return innerDelegate.GetMethodImpl();
 | |
|                 }
 | |
|             }
 | |
|             else if (IsUnmanagedFunctionPtr())
 | |
|             {
 | |
|                 // we handle unmanaged function pointers here because the generic ones (used for WinRT) would otherwise
 | |
|                 // be treated as open delegates by the base implementation, resulting in failure to get the MethodInfo
 | |
|                 if ((_methodBase == null) || !(_methodBase is MethodInfo))
 | |
|                 {
 | |
|                     IRuntimeMethodInfo method = FindMethodHandle();
 | |
|                     RuntimeType declaringType = RuntimeMethodHandle.GetDeclaringType(method);
 | |
| 
 | |
|                     // need a proper declaring type instance method on a generic type
 | |
|                     if (RuntimeTypeHandle.IsGenericTypeDefinition(declaringType) || RuntimeTypeHandle.HasInstantiation(declaringType))
 | |
|                     {
 | |
|                         // we are returning the 'Invoke' method of this delegate so use this.GetType() for the exact type
 | |
|                         RuntimeType reflectedType = GetType() as RuntimeType;
 | |
|                         declaringType = reflectedType;
 | |
|                     }
 | |
|                     _methodBase = (MethodInfo)RuntimeType.GetMethodBase(declaringType, method);
 | |
|                 }
 | |
|                 return (MethodInfo)_methodBase;
 | |
|             }
 | |
| 
 | |
|             // Otherwise, must be an inner delegate of a SecureDelegate of an open virtual method. In that case, call base implementation
 | |
|             return base.GetMethodImpl();
 | |
|         }
 | |
|             
 | |
|         // this should help inlining
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void ThrowNullThisInDelegateToInstance() 
 | |
|         {
 | |
|             throw new ArgumentException(Environment.GetResourceString("Arg_DlgtNullInst"));
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorClosed(Object target, IntPtr methodPtr)
 | |
|         {
 | |
|             if (target == null) 
 | |
|                 ThrowNullThisInDelegateToInstance();
 | |
|             this._target = target;
 | |
|             this._methodPtr = methodPtr;
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorClosedStatic(Object target, IntPtr methodPtr)
 | |
|         {
 | |
|             this._target = target;
 | |
|             this._methodPtr = methodPtr;
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorRTClosed(Object target, IntPtr methodPtr)
 | |
|         {
 | |
|             this._target = target;
 | |
|             this._methodPtr = AdjustTarget(target, methodPtr);
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk)
 | |
|         {
 | |
|             this._target = this;
 | |
|             this._methodPtr = shuffleThunk;
 | |
|             this._methodPtrAux = methodPtr;
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorSecureClosed(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
 | |
|         {
 | |
|             MulticastDelegate realDelegate = (MulticastDelegate)Delegate.InternalAllocLike(this);
 | |
|             realDelegate.CtorClosed(target, methodPtr);
 | |
|             this._invocationList = realDelegate;
 | |
|             this._target = this;
 | |
|             this._methodPtr = callThunk;
 | |
|             this._methodPtrAux = creatorMethod;
 | |
|             this._invocationCount = GetInvokeMethod();
 | |
|         }
 | |
|     
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorSecureClosedStatic(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
 | |
|         {
 | |
|             MulticastDelegate realDelegate = (MulticastDelegate)Delegate.InternalAllocLike(this);
 | |
|             realDelegate.CtorClosedStatic(target, methodPtr);
 | |
|             this._invocationList = realDelegate;
 | |
|             this._target = this;
 | |
|             this._methodPtr = callThunk;
 | |
|             this._methodPtrAux = creatorMethod;
 | |
|             this._invocationCount = GetInvokeMethod();
 | |
|         }
 | |
|     
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorSecureRTClosed(Object target, IntPtr methodPtr, IntPtr callThunk, IntPtr creatorMethod)
 | |
|         {
 | |
|             MulticastDelegate realDelegate = Delegate.InternalAllocLike(this);
 | |
|             realDelegate.CtorRTClosed(target, methodPtr);
 | |
|             this._invocationList = realDelegate;
 | |
|             this._target = this;
 | |
|             this._methodPtr = callThunk;
 | |
|             this._methodPtrAux = creatorMethod;
 | |
|             this._invocationCount = GetInvokeMethod();
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorSecureOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr callThunk, IntPtr creatorMethod)
 | |
|         {
 | |
|             MulticastDelegate realDelegate = Delegate.InternalAllocLike(this);
 | |
|             realDelegate.CtorOpened(target, methodPtr, shuffleThunk);
 | |
|             this._invocationList = realDelegate;
 | |
|             this._target = this;
 | |
|             this._methodPtr = callThunk;
 | |
|             this._methodPtrAux = creatorMethod;
 | |
|             this._invocationCount = GetInvokeMethod();
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorVirtualDispatch(Object target, IntPtr methodPtr, IntPtr shuffleThunk)
 | |
|         {
 | |
|             this._target = this;
 | |
|             this._methodPtr = shuffleThunk;
 | |
|             this._methodPtrAux = GetCallStub(methodPtr);
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorSecureVirtualDispatch(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr callThunk, IntPtr creatorMethod)
 | |
|         {
 | |
|             MulticastDelegate realDelegate = Delegate.InternalAllocLike(this);
 | |
|             realDelegate.CtorVirtualDispatch(target, methodPtr, shuffleThunk);
 | |
|             this._invocationList = realDelegate;
 | |
|             this._target = this;
 | |
|             this._methodPtr = callThunk;
 | |
|             this._methodPtrAux = creatorMethod;
 | |
|             this._invocationCount = GetInvokeMethod();
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorCollectibleClosedStatic(Object target, IntPtr methodPtr, IntPtr gchandle)
 | |
|         {
 | |
|             this._target = target;
 | |
|             this._methodPtr = methodPtr;
 | |
|             this._methodBase = System.Runtime.InteropServices.GCHandle.InternalGet(gchandle);
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorCollectibleOpened(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr gchandle)
 | |
|         {
 | |
|             this._target = this;
 | |
|             this._methodPtr = shuffleThunk;
 | |
|             this._methodPtrAux = methodPtr;
 | |
|             this._methodBase = System.Runtime.InteropServices.GCHandle.InternalGet(gchandle);
 | |
|         }
 | |
| 
 | |
|         [System.Security.SecurityCritical]  // auto-generated
 | |
|         [System.Diagnostics.DebuggerNonUserCode]
 | |
|         private void CtorCollectibleVirtualDispatch(Object target, IntPtr methodPtr, IntPtr shuffleThunk, IntPtr gchandle)
 | |
|         {
 | |
|             this._target = this;
 | |
|             this._methodPtr = shuffleThunk;
 | |
|             this._methodPtrAux = GetCallStub(methodPtr);
 | |
|             this._methodBase = System.Runtime.InteropServices.GCHandle.InternalGet(gchandle);
 | |
|         }
 | |
|     }
 | |
| }
 |