コード例 #1
0
        void EmitUsing(LocalBuilder local, System.Action body)
        {
            var endFinally = IL.DefineLabel();

            IL.BeginExceptionBlock();

            body();

            IL.BeginFinallyBlock();

            IL.Emit(OpCodes.Ldloc, local);
            IL.Emit(OpCodes.Ldnull);
            IL.Emit(OpCodes.Beq, endFinally);

            IL.Emit(OpCodes.Ldloc, local);
            IL.Emit(OpCodes.Callvirt, typeof(IDisposable).GetMethod("Dispose"));

            IL.MarkLabel(endFinally);
            IL.EndExceptionBlock();
        }
コード例 #2
0
        /// <summary>
        /// Start a new exception block.  This is roughly analogous to a `try` block in C#, but an exception block contains it's catch and finally blocks.
        /// </summary>
        public ExceptionBlock BeginExceptionBlock()
        {
            if (MustMark)
            {
                MarkLabel(DefineLabel(AutoNamer.Next(this, "__autolabel")));
            }

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

            var labelDel = IL.BeginExceptionBlock();
            var label    = new Label(this, labelDel, AutoNamer.Next(this, "__exceptionBlockEnd"));

            CurrentLabels[label.Name] = label;

            var ret = new ExceptionBlock(label);

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

            CurrentExceptionBlock.Push(ret);

            return(ret);
        }
コード例 #3
0
ファイル: StmtTry.cs プロジェクト: pyzh/ZLanguage3
 public override void Emit( )
 {
     tryLabel = IL.BeginExceptionBlock();
 }
コード例 #4
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);
        }
コード例 #5
0
 private void Try()
 {
     IL.BeginExceptionBlock(); // try {
 }
コード例 #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;
        }