private static void EmitExceptionHandling( TracingILGenerator il, Type returnType, Label endOfMethod, Action<TracingILGenerator, LocalBuilder> exceptionHandlerInvocation ) { il.BeginCatchBlock( typeof( Exception ) ); var exception = il.DeclareLocal( typeof( Exception ), "exception" ); il.EmitAnyStloc( exception ); exceptionHandlerInvocation( il, exception ); il.EmitLeave( endOfMethod ); il.EndExceptionBlock(); }
/// <summary> /// Emits helper function to avoid lexical closure emitting. /// </summary> /// <param name="il"><see cref="TracingILGenerator"/>.</param> /// <param name="targetOperation"><see cref="MethodInfo"/> of the method to be invoked.</param> /// <param name="tupleTypes">The array of <see cref="Type"/> of nested tuples. The outermost is the first, innermost is the last.</param> /// <param name="itemTypes">The array of <see cref="Type"/> of flatten tuple items.</param> private static void EmitPrivateInvoke( TracingILGenerator il, MethodInfo targetOperation, IList<Type> tupleTypes, Type[] itemTypes ) { /* * private void/T PrivateInvoke( object state ) * { * T result; * Dispatcher.BeginOperation(); * try * { * var tuple = state as Tuple<...>; * result = * tuple.Item1.Target( * tuple.Item2, * : * tuple.Rest.Rest....ItemN * ); * } * catch( TheradAbortException ) * { * Dispatcher.HandleThreadAbortException( ex ); * } * finally * { * Dispatcher.EndOperation(); * } * * return result; * } */ var tuple = il.DeclareLocal( tupleTypes.First(), "tuple" ); var result = targetOperation.ReturnType == typeof( void ) ? null : il.DeclareLocal( targetOperation.ReturnType, "result" ); il.EmitAnyLdarg( 0 ); il.EmitCall( _dispatcherBeginOperationMethod ); il.BeginExceptionBlock(); il.EmitAnyLdarg( 1 ); il.EmitIsinst( tupleTypes.First() ); il.EmitAnyStloc( tuple ); int depth = -1; for ( int i = 0; i < itemTypes.Length; i++ ) { if ( i % 7 == 0 ) { depth++; } il.EmitAnyLdloc( tuple ); for ( int j = 0; j < depth; j++ ) { // .TRest.TRest ... var rest = tupleTypes[ j ].GetProperty( "Rest" ); il.EmitGetProperty( rest ); } var itemn = tupleTypes[ depth ].GetProperty( "Item" + ( ( i % 7 ) + 1 ) ); il.EmitGetProperty( itemn ); } il.EmitAnyCall( targetOperation ); if ( targetOperation.ReturnType != typeof( void ) ) { il.EmitAnyStloc( result ); } il.BeginCatchBlock( typeof( ThreadAbortException ) ); var ex = il.DeclareLocal(typeof(ThreadAbortException), "ex"); il.EmitAnyStloc( ex ); il.EmitAnyLdarg( 0 ); il.EmitAnyLdloc( ex ); il.EmitCall( _dispatcherHandleThreadAbortExceptionMethod ); il.BeginFinallyBlock(); il.EmitAnyLdarg( 0 ); il.EmitCall( _dispatcherEndOperationMethod ); il.EndExceptionBlock(); if ( targetOperation.ReturnType != typeof( void ) ) { il.EmitAnyLdloc( result ); } il.EmitRet(); }