예제 #1
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);
        }
        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;
        }