Пример #1
0
        /// <summary>
        /// Ends the given finally block.
        /// </summary>
        public Emit <DelegateType> EndFinallyBlock(FinallyBlock forFinally)
        {
            if (forFinally == null)
            {
                throw new ArgumentNullException("forFinally");
            }

            if (((IOwned)forFinally).Owner != this)
            {
                FailOwnership(forFinally);
            }

            var finallyBlock = FinallyBlocks[forFinally];

            if (finallyBlock.Item2 != -1)
            {
                throw new InvalidOperationException("EndFinallyBlock expects an unclosed finally block, but " + forFinally + " is already closed");
            }

            if (MustMark)
            {
                MarkLabel(DefineLabel(AutoNamer.Next(this, "__autolabel")));
            }

            UpdateState(Wrap(new[] { new StackTransition(0) }, "EndFinallyBlock"));

            IL.EndFinallyBlock();

            FinallyBlocks[forFinally] = SigilTuple.Create(finallyBlock.Item1, IL.Index);

            return(this);
        }
Пример #2
0
        /// <summary>
        /// Begins a finally block on the given exception block.
        ///
        /// Only one finally block can be defined per exception block, and the block cannot appear within a catch block.
        ///
        /// The given exception block must still be open.
        /// </summary>
        public FinallyBlock BeginFinallyBlock(ExceptionBlock forTry)
        {
            if (forTry == null)
            {
                throw new ArgumentNullException("forTry");
            }

            if (((IOwned)forTry).Owner != this)
            {
                FailOwnership(forTry);
            }

            var tryBlock = TryBlocks[forTry];

            if (tryBlock.Item2 != -1)
            {
                throw new InvalidOperationException("BeginFinallyBlock expects an unclosed exception block, but " + forTry + " is already closed");
            }

            if (CurrentExceptionBlock.Count > 0 && forTry != CurrentExceptionBlock.Peek())
            {
                throw new InvalidOperationException("Cannot begin FinallyBlock on " + forTry + " while inner ExceptionBlock " + CurrentExceptionBlock.Peek() + " is still open");
            }

            if (FinallyBlocks.Any(kv => kv.Key.ExceptionBlock == forTry))
            {
                throw new InvalidOperationException("There can only be one finally block per ExceptionBlock, and one is already defined for " + forTry);
            }

            if (MustMark)
            {
                MarkLabel(DefineLabel(AutoNamer.Next(this, "__autolabel")));
            }

            UpdateState(Wrap(new[] { new StackTransition(0) }, "BeginFinallyBlock"));

            var ret = new FinallyBlock(forTry);

            IL.BeginFinallyBlock();

            FinallyBlocks[ret] = SigilTuple.Create(IL.Index, -1);

            return(ret);
        }
Пример #3
0
 /// <summary cref="M:Sigil.Emit`1.EndFinallyBlock(Sigil.FinallyBlock)" />
 public EmitShorthand <DelegateType> EndFinallyBlock(FinallyBlock forFinally)
 {
     InnerEmit.EndFinallyBlock(forFinally);
     return(this);
 }
Пример #4
0
        /// <summary cref="M:Sigil.Emit`1.BeginFinallyBlock(Sigil.ExceptionBlock)" />
        public EmitShorthand <DelegateType> BeginFinallyBlock(ExceptionBlock forTry, out FinallyBlock forFinally)
        {
            forFinally = BeginFinallyBlock(forTry);

            return(this);
        }