Exemple #1
0
        //protected virtual void EmitEventInvocationMethodForWeaklyReferencedEvents(
        //   EventModel eventModel,
        //   CompositeTypeGenerationInfo thisGenerationInfo,
        //   CILField eventField,
        //   CILTypeBase eventType,
        //   CompositeMethodGenerationInfo invokeMethod,
        //   CILMethod eventMethodToInvoke
        //   )
        //{
        //   //   EventHandlerInfoArrayWrapper wrapper = this._myEventManualWeak;
        //   //   if ( wrapper != null )
        //   //   {
        //   //      EventHandlerInfo[] evts = wrapper.Array;
        //   //      Boolean cleanUp = false;
        //   //      try
        //   //      {
        //   //      for ( Int32 idx = 0; idx < wrapper.ElementCount; ++idx )
        //   //      {
        //   //         EventHandlerInfo info = evts[idx];
        //   //         Object target = info.Target;
        //   //         if ( EventHandlerInfoArrayWrapper.IsDead( info ) )
        //   //         {
        //   //            cleanUp = true;
        //   //         }
        //   //         else
        //   //         {
        //   //            (result) = new <event type>(target, info.Method).Invoke(params);
        //   //         }
        //   //      }
        //   //
        //   //      }
        //   //      finally
        //   //      {
        //   //      if ( cleanUp )
        //   //      {
        //   //         Interlocked.CompareExchange( ref this._myEventManualWeak, EventHandlerInfoArrayWrapper.CleanUp( wrapper ), wrapper );
        //   //      }
        //   //      }
        //   //   }

        //   this.EmitEventInvocationMethodCore(
        //      eventModel,
        //      thisGenerationInfo,
        //      eventField,
        //      WEAK_EVENT_WRAPPER_TYPE,
        //      invokeMethod,
        //      eventMethodToInvoke,
        //      ( eventLB, invocationStyle, exceptionType ) =>
        //      {
        //         var il = invokeMethod.IL;

        //         //      EventHandlerInfo[] evts = wrapper.Array;
        //         var evtsArrayB = il.DeclareLocal( WEAK_EVENT_ARRAY_WRAPPER_ARRAY_GETTER.GetReturnType() );
        //         il
        //            .EmitLoadLocal( eventLB )
        //            .EmitCall( WEAK_EVENT_ARRAY_WRAPPER_ARRAY_GETTER )
        //            .EmitStoreLocal( evtsArrayB );

        //         //      Boolean cleanUp = false;
        //         var cleanUpB = il.DeclareLocal( BOOLEAN_TYPE );
        //         il
        //            .EmitLoadBoolean( false )
        //            .EmitStoreLocal( cleanUpB );

        //         Boolean countingDead = !VOID_TYPE.Equals( invokeMethod.ReturnType );
        //         // Int32 amountOfDead = wrapper.ElementCount;
        //         LocalBuilder amountOfDeadB = null;
        //         if ( countingDead )
        //         {
        //            amountOfDeadB = invokeMethod.GetOrCreateLocal( LB_AMOUNT_OF_DEAD_EVENT_INFOS );
        //            il
        //               .EmitLoadLocal( eventLB )
        //               .EmitCall( WEAK_EVENT_ARRAY_WRAPPER_COUNT_GETTER )
        //               .EmitStoreLocal( amountOfDeadB );
        //         }

        //         il.EmitTryFinally(
        //            il2 => il2.EmitSimpleForLoop(
        //               il3 =>
        //               {
        //                  // Int32 idx = 0
        //                  var idxB = invokeMethod.GetOrCreateLocal( LB_INDEX );
        //                  il3
        //                     .EmitLoadInt32( 0 )
        //                     .EmitStoreLocal( idxB );
        //                  return idxB;
        //               },
        //               ( il3, idxB, loopBodyStartLabel ) =>
        //               {
        //                  // idx < wrapper.ElementCount
        //                  il3
        //                     .EmitLoadLocal( idxB )
        //                     .EmitLoadLocal( eventLB )
        //                     .EmitCall( WEAK_EVENT_ARRAY_WRAPPER_COUNT_GETTER )
        //                     .EmitBranch( BranchType.IF_FIRST_LESSER_THAN_SECOND, loopBodyStartLabel );
        //               },
        //               E_MethodIL.EmitLeftPlusPlus,
        //               ( il3, idxB ) =>
        //               {
        //                  var infoB = il3.DeclareLocal( evtsArrayB.LocalType.GetElementType() );

        //                  //         EventHandlerInfo info = evts[idx];
        //                  il3
        //                     .EmitLoadLocal( evtsArrayB )
        //                     .EmitLoadLocal( idxB )
        //                     .EmitLoadElement( evtsArrayB.LocalType )
        //                     .EmitStoreLocal( infoB );

        //                  //         Object target = info.Target;
        //                  var targetB = il3.DeclareLocal( EVENT_INFO_TARGET_GETTER.GetReturnType() );
        //                  il3
        //                     .EmitLoadLocal( infoB )
        //                     .EmitCall( EVENT_INFO_TARGET_GETTER )
        //                     .EmitStoreLocal( targetB );

        //                  il3.EmitIfElse(
        //                     ( il4, elseLabel, endIfLabel ) =>
        //                     {
        //                        il4
        //                           .EmitLoadLocal( infoB )
        //                           // TODO write out is dead -method
        //                           .EmitCall( IS_EVENT_INFO_DEAD_METHOD )
        //                           .EmitBranch( BranchType.IF_TRUE, elseLabel );
        //                     },
        //                     ( il4, elseLabel, endIfLabel ) =>
        //                     {
        //                        // (result) = new <event type>(target, info.Method).Invoke(params);

        //                        // TODO TODO TODO
        //                        // Consider changing info.Method into returning MethodInfo object, and then
        //                        // use info.Method.Invoke(target, params).
        //                        // Slower, but works with .NET 4 portable and PEVerifier won't give errors/warnings.
        //                        this.EmitEventInvocationWithTryCatchIfNeeded(
        //                           invocationStyle,
        //                           exceptionType,
        //                           invokeMethod,
        //                           eventMethodToInvoke,
        //                           il5 =>
        //                           {
        //                              il5
        //                                 .EmitLoadLocal( targetB )

        //                                 .EmitLoadLocal( infoB )
        //                                 .EmitCall( EVENT_INFO_METHOD_GETTER )
        //                                 .EmitNewObject( TypeGenerationUtils.GetMethodForEmitting( decType => TypeGenerationUtils.CreateTypeForEmittingCILType( decType, thisGenerationInfo.GenericArguments, null ), eventModel.NativeInfo.EventHandlerType.LoadConstructorOrThrow( 2 ).NewWrapper( this.ctx ) ) );
        //                           },
        //                           true
        //                           );
        //                     },
        //                     ( il4, endIfLabel ) =>
        //                     {
        //                        // cleanUp = true;
        //                        il4
        //                           .EmitLoadBoolean( true )
        //                           .EmitStoreLocal( cleanUpB );

        //                        if ( amountOfDeadB != null )
        //                        {
        //                           // --amountOfDead
        //                           il4.EmitLeftMinusMinus( amountOfDeadB );
        //                        }
        //                     }
        //                     );
        //               }
        //            ),
        //            il2 =>
        //               //      if ( cleanUp )
        //               //      {
        //               //         Interlocked.CompareExchange( ref this._myEventManualWeak, EventHandlerInfoArrayWrapper.CleanUp( wrapper ), wrapper );
        //               //      }
        //               il2.EmitIf(
        //               ( il3, endIfLabel ) =>
        //               {
        //                  il3
        //                     .EmitLoadLocal( cleanUpB )
        //                     .EmitBranch( BranchType.IF_FALSE, endIfLabel );
        //               },
        //               ( il3, endIfLabel ) =>
        //               {
        //                  il3
        //                     .EmitLoadThisFieldAddress( eventField )

        //                     .EmitLoadLocal( eventLB )
        //                     .EmitCall( WEAK_EVENT_ARRAY_CLEANUP_METHOD )

        //                     .EmitLoadLocal( eventLB )

        //                     .EmitCall( INTERLOCKED_COMPARE_EXCHANGE_METHOD_GDEF.MakeGenericMethod( eventLB.LocalType ) )
        //                     .EmitPop();
        //               }
        //            ) );
        //      } );
        //}

        //protected virtual void EmitEventAdditionMethodForWeaklyReferencedEvents(
        //   CILField eventField,
        //   MethodIL il
        //   )
        //{
        //   //Delegate[] invocations = <arg-1>.GetInvocationList();
        //   //EventHandlerInfo[] evtsToAdd = new EventHandlerInfo[invocations.Length];
        //   //for ( Int32 i = 0; i < invocations.Length; ++i )
        //   //{
        //   //   evtsToAdd[i] = new EventHandlerInfo( invocations[i] );
        //   //}

        //   //EventHandlerInfoArrayWrapper current = this._myEventManualWeak;
        //   //EventHandlerInfoArrayWrapper oldCurrent, combined;
        //   //do
        //   //{
        //   //   oldCurrent = EventHandlerInfoArrayWrapper.CleanUp( current );
        //   //   combined = EventHandlerInfoArrayWrapper.Combine( oldCurrent, evtsToAdd );
        //   //   current = Interlocked.CompareExchange( ref this._myEventManualWeak, combined, oldCurrent );
        //   //} while ( !Object.ReferenceEquals( current, oldCurrent ) );

        //   var invocationsB = il.DeclareLocal( GET_INVOCATION_LIST_METHOD.GetReturnType() );
        //   il
        //      .EmitLoadArg( 1 )
        //      .EmitCall( GET_INVOCATION_LIST_METHOD )
        //      .EmitStoreLocal( invocationsB );

        //   var evtsToAddB = il.DeclareLocal( STRONG_EVENT_WRAPPER_TYPE.MakeArrayType() );
        //   il
        //      .EmitLoadLocal( invocationsB )
        //      .EmitLoadArrayLength()
        //      .EmitNewArray( evtsToAddB.LocalType.GetElementType() )
        //      .EmitStoreLocal( evtsToAddB )

        //      .EmitSimpleForLoop(
        //      il2 =>
        //      {
        //         // Int32 i = 0
        //         var idxB = il.DeclareLocal( LB_INDEX.Type.NewWrapper( this.ctx ) );
        //         il2
        //            .EmitLoadInt32( 0 )
        //            .EmitStoreLocal( idxB );
        //         return idxB;
        //      },
        //      ( il2, idxB, loopBodyStartLabel ) =>
        //      {
        //         // index < evtsToAdd.Length
        //         il2
        //            .EmitLoadLocal( idxB )
        //            .EmitLoadLocal( evtsToAddB )
        //            .EmitLoadArrayLength()
        //            .EmitNumericConversion( CILTypeCode.UInt32, CILTypeCode.Int32, false )
        //            .EmitBranch( BranchType.IF_FIRST_LESSER_THAN_SECOND, loopBodyStartLabel );
        //      },
        //      E_MethodIL.EmitLeftPlusPlus,
        //      ( il2, idxB ) =>
        //      {
        //         il2.EmitLoadLocal( evtsToAddB )
        //            .EmitLoadLocal( idxB )
        //            .EmitLoadLocal( invocationsB )
        //            .EmitLoadLocal( idxB )
        //            .EmitLoadElement( invocationsB.LocalType )
        //            .EmitNewObject( EVENT_INFO_CTOR )
        //            .EmitStoreElement( evtsToAddB.LocalType );
        //      }
        //      )
        //      .EmitInterlockedCompareExchangeFieldSettingLoop(
        //      eventField,
        //      //fieldType,
        //      ( il2, currentB ) =>
        //      {
        //         il2
        //            .EmitLoadLocal( currentB )
        //            .EmitCall( WEAK_EVENT_ARRAY_CLEANUP_METHOD );
        //      },
        //      ( il2, oldCurrentB ) =>
        //      {
        //         il2
        //            .EmitLoadLocal( oldCurrentB )
        //           .EmitLoadLocal( evtsToAddB )
        //           .EmitCall( WEAK_EVENT_ARRAY_COMBINE_METHOD );
        //      }
        //      );
        //   il.EmitReturn();
        //}

        //protected virtual void EmitEventRemovingMethodForWeaklyReferencedEvents(
        //   CILField eventField,
        //   MethodIL il
        //   )
        //{
        //   //Delegate[] invocations = other.GetInvocationList();
        //   //EventHandlerInfoArrayWrapper current = this._myEventManualWeak;
        //   //EventHandlerInfoArrayWrapper oldCurrent, combined;
        //   //do
        //   //{
        //   //   oldCurrent = EventHandlerInfoArrayWrapper.CleanUp( current );
        //   //   combined = EventHandlerInfoArrayWrapper.Remove( oldCurrent, invocations );
        //   //   current = Interlocked.CompareExchange( ref this._myEventManualWeak, combined, oldCurrent );
        //   //} while ( !Object.ReferenceEquals( current, oldCurrent ) );

        //   var invocationsB = il.DeclareLocal( GET_INVOCATION_LIST_METHOD.GetReturnType() );
        //   il
        //      .EmitLoadArg( 1 )
        //      .EmitCall( GET_INVOCATION_LIST_METHOD )
        //      .EmitStoreLocal( invocationsB )

        //      .EmitInterlockedCompareExchangeFieldSettingLoop(
        //      eventField,
        //      ( il2, currentB ) =>
        //      {
        //         il2
        //            .EmitLoadLocal( currentB )
        //            .EmitCall( WEAK_EVENT_ARRAY_CLEANUP_METHOD );
        //      },
        //      ( il2, oldCurrentB ) =>
        //      {
        //         il2
        //            .EmitLoadLocal( oldCurrentB )
        //            .EmitLoadLocal( invocationsB )
        //            .EmitCall( WEAK_EVENT_ARRAY_REMOVE_METHOD );
        //      }
        //      )
        //      .EmitReturn();
        //}

        protected virtual void GetEventInvocationStyle(EventModel eventModel, out EventInvocation invocationStyle, out Type exceptionType)
        {
            EventInvocationStyleAttribute attr = eventModel.AllAttributes.OfType <EventInvocationStyleAttribute>().FirstOrDefault();

            if (attr == null)
            {
                invocationStyle = EventInvocationStyleAttribute.DEFAULT_INVOCATION_STYLE;
                exceptionType   = null;
            }
            else
            {
                invocationStyle = attr.InvocationStyle;
                exceptionType   = attr.RethrowException;
            }
        }
Exemple #2
0
 protected virtual void ValidateEventModel(CompositeValidationResult result, CompositeModel compositeModel, EventModel eventModel)
 {
     if (!typeof(MulticastDelegate).IsAssignableFrom(eventModel.NativeInfo.EventHandlerType))
     {
         result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("All event types must be sub-types of " + typeof(MulticastDelegate) + ".", compositeModel, eventModel));
     }
     else
     {
         IEnumerable <EventInvocationStyleAttribute> attrs = eventModel.AllAttributes.OfType <EventInvocationStyleAttribute>();
         if (attrs.Count() > 1)
         {
             result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("Maximum of one " + typeof(EventInvocationStyleAttribute) + " may be applied on event.", compositeModel, eventModel));
         }
         else
         {
             EventInvocationStyleAttribute attr = attrs.FirstOrDefault();
             if (attr != null && attr.RethrowException != null)
             {
                 if (!typeof(Exception).IsAssignableFrom(attr.RethrowException))
                 {
                     result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The exception type must be derived from " + typeof(Exception), compositeModel, eventModel));
                 }
                 else if (attr.RethrowException.GetConstructor(new Type[] { typeof(Exception[]) }) == null)
                 {
                     result.StructureValidationErrors.Add(ValidationErrorFactory.NewStructureError("The exception to rethrow on event " + eventModel + " invocation must have a public constructor with the following parameters: " + typeof(Exception[]) + ".", compositeModel, eventModel));
                 }
             }
         }
     }
     //else
     //{
     //   Type[] violatingTypes = this.GetAllFragmentMethodsOf( eventModel.AddMethod )
     //      .Concat( this.GetAllFragmentMethodsOf( eventModel.RemoveMethod ) )
     //      .Where( fMethod => !fMethod.NativeInfo.IsAbstract )
     //      .Select( fMethod => fMethod.NativeInfo.DeclaringType )
     //      .Distinct()
     //      .ToArray();
     //   if ( violatingTypes.Any() )
     //   {
     //      result.AddStructureError( new StructureValidationErrorImpl( compositeModel, eventModel, "The following fragment types have non-abstract event declaration: " + String.Join( ", ", (Object[]) violatingTypes ) + "." ) );
     //   }
     //}
 }