Ejemplo n.º 1
0
 public override void Emit()
 {
     //MarkSequencePoint(context);
     IL.BeginCatchBlock(exType.SharpType);
     EmitHelper.StormVar(IL, exSymbol.VarBuilder);
     StmtBody.Emit();
     IL.EndExceptionBlock();
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Begins a catch block for the given exception type in the given exception block.
        ///
        /// The given exception block must still be open.
        /// </summary>
        public CatchBlock BeginCatchBlock(ExceptionBlock forTry, Type exceptionType)
        {
            if (exceptionType == null)
            {
                throw new ArgumentNullException("exceptionType");
            }

            if (forTry == null)
            {
                throw new ArgumentNullException("forTry");
            }

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

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

            if (!typeof(Exception).IsAssignableFrom(exceptionType))
            {
                throw new ArgumentException("BeginCatchBlock expects a type descending from Exception, found " + exceptionType, "exceptionType");
            }

            var currentlyOpen = CatchBlocks.Where(c => c.Key.ExceptionBlock == forTry && c.Value.Item2 == -1).Select(s => s.Key).SingleOrDefault();

            if (currentlyOpen != null)
            {
                throw new InvalidOperationException("Cannot start a new catch block, " + currentlyOpen + " has not been ended");
            }

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

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

            var tryBlock = TryBlocks[forTry];

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

            IL.BeginCatchBlock(exceptionType);

            UpdateState(Wrap(StackTransition.Push(exceptionType), "BeginCatchBlock"));

            var ret = new CatchBlock(exceptionType, forTry);

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

            return(ret);
        }
Ejemplo n.º 3
0
        private void Catch()
        {
            var ex = IL.DeclareLocal(typeof(Exception));

            IL.BeginCatchBlock(typeof(Exception));          // catch
            IL.Emit(OpCodes.Stloc_S, ex);                   // (Exception ex) {
            InvokeOnError(ex);                              //     _callHandler.AfterCall(obj, methodInfo, args);
            IL.EndExceptionBlock();                         // }
        }
Ejemplo n.º 4
0
        private void EmitCatchStart(CatchBlock cb)
        {
            if (cb.Filter == null)
            {
                EmitSaveExceptionOrPop(cb);
                return;
            }

            // emit filter block. Filter blocks are untyped so we need to do
            // the type check ourselves.
            var endFilter = IL.DefineLabel();
            var rightType = IL.DefineLabel();

            // skip if it's not our exception type, but save
            // the exception if it is so it's available to the
            // filter
            IL.Emit(OpCodes.Isinst, cb.Test);
            IL.Emit(OpCodes.Dup);
            IL.Emit(OpCodes.Brtrue, rightType);
            IL.Emit(OpCodes.Pop);
            IL.Emit(OpCodes.Ldc_I4_0);
            IL.Emit(OpCodes.Br, endFilter);

            // it's our type, save it and emit the filter.
            IL.MarkLabel(rightType);
            EmitSaveExceptionOrPop(cb);

            var parent = _labelBlock;

            _labelBlock = new LabelScopeInfo(parent, LabelScopeKind.Filter);

            EmitExpression(cb.Filter);

            _labelBlock = parent;

            // begin the catch, clear the exception, we've
            // already saved it
            IL.MarkLabel(endFilter);
            IL.BeginCatchBlock(null);
            IL.Emit(OpCodes.Pop);
        }
Ejemplo n.º 5
0
        private void EmitTryExpression(Expression expr)
        {
            var node = (TryExpression)expr;

            CheckTry();

            //******************************************************************
            // 1. ENTERING TRY
            //******************************************************************

            PushLabelBlock(LabelScopeKind.Try);
            IL.BeginExceptionBlock();

            //******************************************************************
            // 2. Emit the try statement body
            //******************************************************************

            EmitExpression(node.Body);

            var          tryType = node.Type;
            LocalBuilder value   = null;

            if (tryType != typeof(void))
            {
                //store the value of the try body
                value = GetLocal(tryType);
                IL.Emit(OpCodes.Stloc, value);
            }
            //******************************************************************
            // 3. Emit the catch blocks
            //******************************************************************

            foreach (var cb in node.Handlers)
            {
                PushLabelBlock(LabelScopeKind.Catch);

                // Begin the strongly typed exception block
                if (cb.Filter == null)
                {
                    IL.BeginCatchBlock(cb.Test);
                }
                else
                {
                    IL.BeginExceptFilterBlock();
                }

                EnterScope(cb);

                EmitCatchStart(cb);

                //
                // Emit the catch block body
                //
                EmitExpression(cb.Body);
                if (tryType != typeof(void))
                {
                    //store the value of the catch block body
                    // ReSharper disable once AssignNullToNotNullAttribute
                    IL.Emit(OpCodes.Stloc, value);
                }

                ExitScope(cb);

                PopLabelBlock(LabelScopeKind.Catch);
            }

            //******************************************************************
            // 4. Emit the finally block
            //******************************************************************

            if (node.Finally != null || node.Fault != null)
            {
                PushLabelBlock(LabelScopeKind.Finally);

                if (node.Finally != null)
                {
                    IL.BeginFinallyBlock();
                }
                else
                {
                    IL.BeginFaultBlock();
                }

                // Emit the body
                EmitExpressionAsVoid(node.Finally ?? node.Fault);

                IL.EndExceptionBlock();
                PopLabelBlock(LabelScopeKind.Finally);
            }
            else
            {
                IL.EndExceptionBlock();
            }

            if (tryType != typeof(void))
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                IL.Emit(OpCodes.Ldloc, value);
                FreeLocal(value);
            }

            PopLabelBlock(LabelScopeKind.Try);
        }
Ejemplo n.º 6
0
        private void EmitTryExpression(Expression expr)
        {
            var node = (TryExpression)expr;

            CheckTry(_labelBlock);

            //******************************************************************
            // 1. ENTERING TRY
            //******************************************************************

            var parent = _labelBlock;

            _labelBlock = new LabelScopeInfo(parent, LabelScopeKind.Try);

            IL.BeginExceptionBlock();
            //******************************************************************
            // 2. Emit the try statement body
            //******************************************************************
            EmitExpression(node.Body);
            var          tryType = node.Type;
            LocalBuilder?value   = null;

            if (tryType != typeof(void))
            {
                //store the value of the try body
                value = GetLocal(tryType);
                IL.Emit(OpCodes.Stloc, value);
            }
            //******************************************************************
            // 3. Emit the catch blocks
            //******************************************************************
            foreach (var cb in node.Handlers)
            {
                var tmpParent = _labelBlock;
                _labelBlock = new LabelScopeInfo(tmpParent, LabelScopeKind.Catch);

                // Begin the strongly typed exception block
                if (cb.Filter == null)
                {
                    IL.BeginCatchBlock(cb.Test);
                }
                else
                {
                    IL.BeginExceptFilterBlock();
                }

                var innerScopeInfo = GetInnerScope(node, _scope);
                if (innerScopeInfo.HasValue)
                {
                    _scope = innerScopeInfo.Value.child.Enter(this, innerScopeInfo.Value.parent);
                }

                EmitCatchStart(cb);
                //
                // Emit the catch block body
                //
                EmitExpression(cb.Body);
                if (tryType != typeof(void))
                {
                    //store the value of the catch block body
                    // ReSharper disable once AssignNullToNotNullAttribute
                    IL.Emit(OpCodes.Stloc, value);
                }

                if (innerScopeInfo.HasValue)
                {
                    innerScopeInfo.Value.child.Exit();
                    _scope = innerScopeInfo.Value.parent;
                }

                _labelBlock = tmpParent;
            }
            //******************************************************************
            // 4. Emit the finally block
            //******************************************************************
            if (node.Finally != null || node.Fault != null)
            {
                var tmpParent = _labelBlock;
                _labelBlock = new LabelScopeInfo(tmpParent, LabelScopeKind.Finally);

                if (node.Finally != null)
                {
                    IL.BeginFinallyBlock();
                }
                else
                {
                    IL.BeginFaultBlock();
                }
                // Emit the body
                EmitExpressionAsVoid(node.Finally ?? node.Fault !);
                IL.EndExceptionBlock();

                _labelBlock = tmpParent;
            }
            else
            {
                IL.EndExceptionBlock();
            }
            if (value != null)
            {
                // ReSharper disable once AssignNullToNotNullAttribute
                IL.Emit(OpCodes.Ldloc, value);
                FreeLocal(value);
            }

            _labelBlock = parent;
        }