Пример #1
0
        public void CatchBlockOverloadDoesNotUnbalanceTheStack()
        {
            var method = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes);
            var generator = method.GetILGenerator();
            var il = new ILWriter(generator);

            var exceptionBlock = generator.BeginExceptionBlock();
            generator.Emit(OpCodes.Leave, exceptionBlock);
            il.CatchBlock<Exception>(exceptionBlock, () => { });
            il.VerifyStack();
        }
Пример #2
0
        public void CatchBlockOverloadDoesNotUnbalanceTheStack()
        {
            var method    = new DynamicMethod(String.Empty, typeof(void), Type.EmptyTypes);
            var generator = method.GetILGenerator();
            var il        = new ILWriter(generator);

            var exceptionBlock = generator.BeginExceptionBlock();

            generator.Emit(OpCodes.Leave, exceptionBlock);
            il.CatchBlock <Exception>(exceptionBlock, () => { });
            il.VerifyStack();
        }
Пример #3
0
        private IEnumerable <Action <Label> > WriteUnrolledCatchBlocks(ILWriter writer, IImmutableQueue <Type> exceptionTypes, LocalBuilder shouldRetry, LocalBuilder currentExecutionAttempt)
        {
            var handleException = KnownMetadata.Methods.IExceptionAwareAction_HandleException;

            foreach (var exceptionType in exceptionTypes)
            {
                yield return(endOfTryCatch =>
                {
                    var handleSpecificException = handleException.MakeGenericMethod(exceptionType);

                    Action catchBlockBody = () =>
                    {
                        var endOfCatch = writer.DefineLabel();
                        var localException = writer.DeclareLocal(exceptionType);
                        writer.SetLocal(localException);

                        writer.LoadFirstParameter(); //Exception-aware instance
                        writer.LoadLocal(localException);
                        writer.LoadLocal(currentExecutionAttempt);
                        writer.InstanceMethodCall(handleSpecificException);

                        //The handler refusing to handle it indicates that we should perform a retry.
                        var wasHandled = writer.IfFalseThen();

                        writer.LoadTrue();
                        writer.SetLocal(shouldRetry);
                        writer.GoTo(endOfCatch);

                        writer.MarkLabel(wasHandled);

                        writer.LoadFalse();
                        writer.SetLocal(shouldRetry);

                        writer.MarkLabel(endOfCatch);
                    };

                    writer.CatchBlock(exceptionType, endOfTryCatch, catchBlockBody);
                });
            }
        }