コード例 #1
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (node.ExceptionFilterOpt == null)
            {
                return(base.VisitCatchBlock(node));
            }

            BoundExpression rewrittenExceptionSourceOpt = (BoundExpression)this.Visit(node.ExceptionSourceOpt);
            BoundExpression rewrittenFilter             = (BoundExpression)this.Visit(node.ExceptionFilterOpt);
            BoundBlock      rewrittenBody             = (BoundBlock)this.Visit(node.Body);
            TypeSymbol      rewrittenExceptionTypeOpt = this.VisitType(node.ExceptionTypeOpt);

            // EnC: We need to insert a hidden sequence point to handle function remapping in case
            // the containing method is edited while methods invoked in the condition are being executed.
            if (rewrittenFilter != null && !node.WasCompilerGenerated && this.Instrument)
            {
                rewrittenFilter = _instrumenter.InstrumentCatchClauseFilter(node, rewrittenFilter, _factory);
            }

            return(node.Update(
                       node.Locals,
                       rewrittenExceptionSourceOpt,
                       rewrittenExceptionTypeOpt,
                       rewrittenFilter,
                       rewrittenBody,
                       node.IsSynthesizedAsyncCatchAll));
        }
コード例 #2
0
ファイル: ControlFlowPass.cs プロジェクト: nesclapez/roslyn
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            var oldPending = SavePending(); // we do not support branches into a catch block

            base.VisitCatchBlock(catchBlock, ref finallyState);
            RestorePending(oldPending);
        }
コード例 #3
0
ファイル: BoundNode.cs プロジェクト: zhouweiaccp/roslyn
 public override BoundNode VisitCatchBlock(BoundCatchBlock node)
 {
     AddAll(node.Locals);
     base.VisitCatchBlock(node);
     RemoveAll(node.Locals);
     return(null);
 }
コード例 #4
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (node.ExceptionFilterOpt == null)
            {
                return base.VisitCatchBlock(node);
            }

            BoundExpression rewrittenExceptionSourceOpt = (BoundExpression)this.Visit(node.ExceptionSourceOpt);
            BoundExpression rewrittenFilter = (BoundExpression)this.Visit(node.ExceptionFilterOpt);
            BoundBlock rewrittenBody = (BoundBlock)this.Visit(node.Body);
            TypeSymbol rewrittenExceptionTypeOpt = this.VisitType(node.ExceptionTypeOpt);

            // EnC: We need to insert a hidden sequence point to handle function remapping in case 
            // the containing method is edited while methods invoked in the condition are being executed.
            if (rewrittenFilter != null && !node.WasCompilerGenerated && this.Instrument)
            {
                rewrittenFilter = _instrumenter.InstrumentCatchClauseFilter(node, rewrittenFilter, _factory);
            }

            return node.Update(
                node.Locals,
                rewrittenExceptionSourceOpt,
                rewrittenExceptionTypeOpt,
                rewrittenFilter,
                rewrittenBody,
                node.IsSynthesizedAsyncCatchAll);
        }
コード例 #5
0
 public virtual BoundExpression InstrumentCatchClauseFilter(BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory)
 {
     Debug.Assert(!original.WasCompilerGenerated);
     Debug.Assert(original.Syntax.Kind() == SyntaxKind.CatchClause);
     Debug.Assert(((CatchClauseSyntax)original.Syntax).Filter != null);
     Debug.Assert(factory != null);
     return(rewrittenFilter);
 }
コード例 #6
0
ファイル: CompoundInstrumenter.cs プロジェクト: belav/roslyn
 public override BoundExpression InstrumentCatchClauseFilter(
     BoundCatchBlock original,
     BoundExpression rewrittenFilter,
     SyntheticBoundNodeFactory factory
     )
 {
     return(Previous.InstrumentCatchClauseFilter(original, rewrittenFilter, factory));
 }
コード例 #7
0
        public override BoundExpression InstrumentCatchClauseFilter(BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory)
        {
            rewrittenFilter = base.InstrumentCatchClauseFilter(original, rewrittenFilter, factory);

            // EnC: We need to insert a hidden sequence point to handle function remapping in case
            // the containing method is edited while methods invoked in the condition are being executed.
            CatchFilterClauseSyntax filterClause = ((CatchClauseSyntax)original.Syntax).Filter;

            return(AddConditionSequencePoint(new BoundSequencePointExpression(filterClause, rewrittenFilter, rewrittenFilter.Type), filterClause, factory));
        }
コード例 #8
0
                public override BoundNode VisitCatchBlock(BoundCatchBlock node)
                {
                    var oldScope = _currentScope;

                    _currentScope = CreateOrReuseScope(node, node.Locals);
                    var result = base.VisitCatchBlock(node);

                    _currentScope = oldScope;
                    return(result);
                }
コード例 #9
0
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            if (IsInside)
            {
                if ((object)catchBlock.LocalOpt != null)
                {
                    variablesDeclared.Add(catchBlock.LocalOpt);
                }
            }

            base.VisitCatchBlock(catchBlock, ref finallyState);
        }
コード例 #10
0
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            if (IsInside)
            {
                var local = catchBlock.Locals.FirstOrDefault();

                if (local?.DeclarationKind == LocalDeclarationKind.CatchVariable)
                {
                    _variablesDeclared.Add(local);
                }
            }

            base.VisitCatchBlock(catchBlock, ref finallyState);
        }
コード例 #11
0
ファイル: LambdaRewriter.cs プロジェクト: SkightTeam/roslyn
        private BoundNode RewriteCatch(BoundCatchBlock node, ArrayBuilder <BoundExpression> prologue, ArrayBuilder <LocalSymbol> newLocals)
        {
            AddLocals(node.Locals, newLocals);
            var rewrittenCatchLocals = newLocals.ToImmutableAndFree();

            // If exception variable got lifted, IntroduceFrame will give us frame init prologue.
            // It needs to run before the exception variable is accessed.
            // To ensure that, we will make exception variable a sequence that performs prologue as its its sideeffecs.
            BoundExpression rewrittenExceptionSource = null;
            var             rewrittenFilter          = (BoundExpression)this.Visit(node.ExceptionFilterOpt);

            if (node.ExceptionSourceOpt != null)
            {
                rewrittenExceptionSource = (BoundExpression)Visit(node.ExceptionSourceOpt);
                if (prologue.Count > 0)
                {
                    rewrittenExceptionSource = new BoundSequence(
                        rewrittenExceptionSource.Syntax,
                        ImmutableArray.Create <LocalSymbol>(),
                        prologue.ToImmutable(),
                        rewrittenExceptionSource,
                        rewrittenExceptionSource.Type);
                }
            }
            else if (prologue.Count > 0)
            {
                Debug.Assert(rewrittenFilter != null);
                rewrittenFilter = new BoundSequence(
                    rewrittenFilter.Syntax,
                    ImmutableArray.Create <LocalSymbol>(),
                    prologue.ToImmutable(),
                    rewrittenFilter,
                    rewrittenFilter.Type);
            }

            // done with this.
            prologue.Free();

            // rewrite filter and body
            // NOTE: this will proxy all accesses to exception local if that got lifted.
            var exceptionTypeOpt = this.VisitType(node.ExceptionTypeOpt);
            var rewrittenBlock   = (BoundBlock)this.Visit(node.Body);

            return(node.Update(
                       rewrittenCatchLocals,
                       rewrittenExceptionSource,
                       exceptionTypeOpt,
                       rewrittenFilter,
                       rewrittenBlock));
        }
コード例 #12
0
            public override BoundNode VisitCatchBlock(BoundCatchBlock node)
            {
                var locals = node.Locals;

                if (locals.IsDefaultOrEmpty)
                {
                    return(base.VisitCatchBlock(node));
                }

                var previousBlock = PushBlock(node, locals);
                var result        = base.VisitCatchBlock(node);

                PopBlock(previousBlock);
                return(node);
            }
コード例 #13
0
        protected virtual void VisitCatchBlock(BoundCatchBlock catchBlock, ref TLocalState finallyState)
        {
            if (catchBlock.ExceptionSourceOpt != null)
            {
                VisitLvalue(catchBlock.ExceptionSourceOpt);
            }

            if (catchBlock.ExceptionFilterOpt != null)
            {
                VisitCondition(catchBlock.ExceptionFilterOpt);
                SetState(StateWhenTrue);
            }

            VisitStatement(catchBlock.Body);
        }
コード例 #14
0
            public override BoundNode VisitCatchBlock(BoundCatchBlock node)
            {
                var local = node.LocalOpt;

                if ((object)local == null)
                {
                    return(base.VisitCatchBlock(node));
                }

                var previousBlock = PushBlock(node, ImmutableArray.Create(local));
                var result        = base.VisitCatchBlock(node);

                PopBlock(previousBlock);
                return(node);
            }
コード例 #15
0
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            if (IsInside)
            {
                var local = catchBlock.LocalOpt;

                if ((object)local != null)
                {
                    Debug.Assert(local.DeclarationKind == LocalDeclarationKind.CatchVariable);
                    variablesDeclared.Add(local);
                }
            }

            base.VisitCatchBlock(catchBlock, ref finallyState);
        }
コード例 #16
0
ファイル: LambdaRewriter.cs プロジェクト: SkightTeam/roslyn
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            // Test if this frame has captured variables and requires the introduction of a closure class.
            LambdaFrame frame;

            if (frames.TryGetValue(node, out frame))
            {
                return(IntroduceFrame(node, frame, (ArrayBuilder <BoundExpression> prologue, ArrayBuilder <LocalSymbol> newLocals) =>
                {
                    return RewriteCatch(node, prologue, newLocals);
                }));
            }
            else
            {
                return(RewriteCatch(node, ArrayBuilder <BoundExpression> .GetInstance(), ArrayBuilder <LocalSymbol> .GetInstance()));
            }
        }
コード例 #17
0
ファイル: LambdaRewriter.cs プロジェクト: SkightTeam/roslyn
 public override BoundNode VisitCatchBlock(BoundCatchBlock node)
 {
     try
     {
         if ((object)node.LocalOpt != null)
         {
             localsDefined.Add(node.LocalOpt);
         }
         return(base.VisitCatchBlock(node));
     }
     finally
     {
         if ((object)node.LocalOpt != null)
         {
             localsDefined.Remove(node.LocalOpt);
         }
     }
 }
コード例 #18
0
            public override BoundNode VisitCatchBlock(BoundCatchBlock node)
            {
                var origSeenAwait = _seenAwait;

                _seenAwait = false;

                var result = base.VisitCatchBlock(node);

                if (_seenAwait)
                {
                    var awaitContainingCatches = _awaitContainingCatches;
                    if (awaitContainingCatches == null)
                    {
                        _awaitContainingCatches = awaitContainingCatches = new HashSet <BoundCatchBlock>();
                    }

                    _awaitContainingCatches.Add(node);
                }

                _seenAwait |= origSeenAwait;
                return(result);
            }
コード例 #19
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (node.ExceptionFilterOpt == null)
            {
                return base.VisitCatchBlock(node);
            }

            BoundExpression rewrittenExceptionSourceOpt = (BoundExpression)this.Visit(node.ExceptionSourceOpt);
            BoundExpression rewrittenFilter = (BoundExpression)this.Visit(node.ExceptionFilterOpt);
            BoundBlock rewrittenBody = (BoundBlock)this.Visit(node.Body);
            TypeSymbol rewrittenExceptionTypeOpt = this.VisitType(node.ExceptionTypeOpt);

            // EnC: We need to insert a hidden sequence point to handle function remapping in case 
            // the containing method is edited while methods invoked in the condition are being executed.
            return node.Update(
                node.Locals,
                rewrittenExceptionSourceOpt,
                rewrittenExceptionTypeOpt,
                AddConditionSequencePoint(rewrittenFilter, node),
                rewrittenBody,
                node.IsSynthesizedAsyncCatchAll);
        }
コード例 #20
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (node.ExceptionFilterOpt == null)
            {
                return(base.VisitCatchBlock(node));
            }

            BoundExpression rewrittenExceptionSourceOpt = (BoundExpression)this.Visit(node.ExceptionSourceOpt);
            BoundExpression rewrittenFilter             = (BoundExpression)this.Visit(node.ExceptionFilterOpt);
            BoundBlock      rewrittenBody             = (BoundBlock)this.Visit(node.Body);
            TypeSymbol      rewrittenExceptionTypeOpt = this.VisitType(node.ExceptionTypeOpt);

            // EnC: We need to insert a hidden sequence point to handle function remapping in case
            // the containing method is edited while methods invoked in the condition are being executed.
            return(node.Update(
                       node.LocalOpt,
                       rewrittenExceptionSourceOpt,
                       rewrittenExceptionTypeOpt,
                       AddConditionSequencePoint(rewrittenFilter, node),
                       rewrittenBody,
                       node.IsSynthesizedAsyncCatchAll));
        }
コード例 #21
0
        private void VisitCatchBlockWithUnassignments(BoundCatchBlock catchBlock, ref TLocalState finallyState)
        {
            if (_trackUnassignments)
            {
                Optional <TLocalState> oldTryState = _tryState;
                _tryState = AllBitsSet();
                VisitCatchBlock(catchBlock, ref finallyState);
                var tempTryStateValue = _tryState.Value;
                IntersectWith(ref finallyState, ref tempTryStateValue);
                if (oldTryState.HasValue)
                {
                    var oldTryStateValue = oldTryState.Value;
                    IntersectWith(ref oldTryStateValue, ref tempTryStateValue);
                    oldTryState = oldTryStateValue;
                }

                _tryState = oldTryState;
            }
            else
            {
                VisitCatchBlock(catchBlock, ref finallyState);
            }
        }
コード例 #22
0
 internal BoundExpression AddConditionSequencePoint(BoundExpression condition, BoundCatchBlock containingCatchWithFilter)
 {
     Debug.Assert(containingCatchWithFilter.ExceptionFilterOpt.Syntax.IsKind(SyntaxKind.CatchFilterClause));
     return AddConditionSequencePoint(condition, containingCatchWithFilter.ExceptionFilterOpt.Syntax, containingCatchWithFilter.WasCompilerGenerated);
 }
コード例 #23
0
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            if (IsInside)
            {
                var local = catchBlock.LocalOpt;

                if ((object)local != null)
                {
                    Debug.Assert(local.DeclarationKind == LocalDeclarationKind.CatchVariable);
                    _variablesDeclared.Add(local);
                }
            }

            base.VisitCatchBlock(catchBlock, ref finallyState);
        }
コード例 #24
0
 public override BoundNode VisitCatchBlock(BoundCatchBlock node)
 {
     AddVariable(node.LocalOpt);
     return base.VisitCatchBlock(node);
 }
コード例 #25
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (!analysis.CatchContainsAwait(node))
            {
                return((BoundCatchBlock)base.VisitCatchBlock(node));
            }

            var currentAwaitCatchFrame = this.currentAwaitCatchFrame;

            if (currentAwaitCatchFrame == null)
            {
                currentAwaitCatchFrame = this.currentAwaitCatchFrame = new AwaitCatchFrame(F);
            }

            var catchType = node.ExceptionTypeOpt ?? F.SpecialType(SpecialType.System_Object);
            var catchTemp = F.SynthesizedLocal(catchType);

            var storePending = F.AssignmentExpression(
                F.Local(currentAwaitCatchFrame.pendingCaughtException),
                F.Convert(currentAwaitCatchFrame.pendingCaughtException.Type,
                          F.Local(catchTemp)));

            var setPendingCatchNum = F.Assignment(
                F.Local(currentAwaitCatchFrame.pendingCatch),
                F.Literal(currentAwaitCatchFrame.handlers.Count + 1));

            //  catch (ExType exTemp)
            //  {
            //      pendingCaughtException = exTemp;
            //      catchNo = X;
            //  }
            BoundCatchBlock catchAndPend;
            ImmutableArray <LocalSymbol> handlerLocals;

            var filterOpt = node.ExceptionFilterOpt;

            if (filterOpt == null)
            {
                // store pending exception
                // as the first statement in a catch
                catchAndPend = node.Update(
                    catchTemp,
                    F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: null,
                    body: F.Block(
                        F.HiddenSequencePoint(),
                        F.ExpressionStatement(storePending),
                        setPendingCatchNum));

                // catch local lives on the synthetic catch handler block
                handlerLocals = node.LocalOpt == null ?
                                ImmutableArray <LocalSymbol> .Empty :
                                ImmutableArray.Create(node.LocalOpt);
            }
            else
            {
                // catch local moves up into hoisted locals
                // since we might need to access it from both the filter and the catch
                handlerLocals = ImmutableArray <LocalSymbol> .Empty;
                if (node.LocalOpt != null)
                {
                    currentAwaitCatchFrame.HoistLocal(node.LocalOpt, F);
                }

                // store pending exception
                // as the first expression in a filter
                var sourceOpt       = node.ExceptionSourceOpt;
                var rewrittenFilter = (BoundExpression)this.Visit(filterOpt);
                var newFilter       = sourceOpt == null?
                                      F.Sequence(
                    storePending,
                    rewrittenFilter) :
                                          F.Sequence(
                                              storePending,
                                              AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame),
                                              rewrittenFilter);

                catchAndPend = node.Update(
                    catchTemp,
                    F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: newFilter,
                    body: F.Block(
                        F.HiddenSequencePoint(),
                        setPendingCatchNum));
            }

            var handlerStatements = ArrayBuilder <BoundStatement> .GetInstance();

            handlerStatements.Add(F.HiddenSequencePoint());

            if (filterOpt == null)
            {
                var sourceOpt = node.ExceptionSourceOpt;
                if (sourceOpt != null)
                {
                    BoundExpression assignSource = AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame);
                    handlerStatements.Add(F.ExpressionStatement(assignSource));
                }
            }

            handlerStatements.Add((BoundStatement)this.Visit(node.Body));

            var handler = F.Block(
                handlerLocals,
                handlerStatements.ToImmutableAndFree()
                );

            currentAwaitCatchFrame.handlers.Add(handler);

            return(catchAndPend);
        }
コード例 #26
0
        private BoundNode RewriteCatch(BoundCatchBlock node, ArrayBuilder <BoundExpression> prologue, ArrayBuilder <LocalSymbol> newLocals)
        {
            LocalSymbol rewrittenCatchLocal = null;

            if (newLocals.Count > 0)
            {
                Debug.Assert(newLocals.Count == 1, "must be only one local that is the frame reference");
                Debug.Assert(this.proxies.ContainsKey(node.LocalOpt), "original local should be proxied");

                // getting new locals means that our original local was lifted into a closure
                // and instead of an actual local catch will own frame reference.
                rewrittenCatchLocal = newLocals[0];
            }
            else if (node.LocalOpt != null)
            {
                // local was not lifted, but its type may need to be rewritten
                // this happens when it has a generic type which needs to be rewritten
                // when lambda body was moved to a separate method.
                var origLocal = node.LocalOpt;
                Debug.Assert(!this.proxies.ContainsKey(origLocal), "captured local should not need rewriting");

                var newType = VisitType(origLocal.Type);
                if (newType == origLocal.Type)
                {
                    // keeping same local
                    rewrittenCatchLocal = origLocal;
                }
                else
                {
                    //  need a local of a different type
                    rewrittenCatchLocal = new SynthesizedLocal(CurrentMethod, newType, origLocal.Name, declarationKind: LocalDeclarationKind.Catch);
                    localMap.Add(origLocal, rewrittenCatchLocal);
                }
            }

            // If exception variable got lifted, IntroduceFrame will give us frame init prologue.
            // It needs to run before the exception variable is accessed.
            // To ensure that, we will make exception variable a sequence that performs prologue as its its sideeffecs.
            BoundExpression rewrittenExceptionSource = null;

            if (node.ExceptionSourceOpt != null)
            {
                rewrittenExceptionSource = (BoundExpression)Visit(node.ExceptionSourceOpt);
                if (prologue.Count > 0)
                {
                    rewrittenExceptionSource = new BoundSequence(
                        rewrittenExceptionSource.Syntax,
                        ImmutableArray.Create <LocalSymbol>(),
                        prologue.ToImmutable(),
                        rewrittenExceptionSource,
                        rewrittenExceptionSource.Type);
                }
            }

            // done with these.
            newLocals.Free();
            prologue.Free();

            // rewrite filter and body
            // NOTE: this will proxy all accesses to exception local if that got lifted.
            var exceptionTypeOpt = this.VisitType(node.ExceptionTypeOpt);
            var rewrittenFilter  = (BoundExpression)this.Visit(node.ExceptionFilterOpt);
            var rewrittenBlock   = (BoundBlock)this.Visit(node.Body);

            return(node.Update(
                       rewrittenCatchLocal,
                       rewrittenExceptionSource,
                       exceptionTypeOpt,
                       rewrittenFilter,
                       rewrittenBlock));
        }
コード例 #27
0
 /// <summary>
 /// Returns true if a catch contains awaits
 /// </summary>
 internal bool CatchContainsAwait(BoundCatchBlock node)
 {
     return(_awaitContainingCatches != null && _awaitContainingCatches.Contains(node));
 }
コード例 #28
0
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            if (IsInside)
            {
                var local = catchBlock.Locals.FirstOrDefault();

                if (local?.DeclarationKind == LocalDeclarationKind.CatchVariable)
                {
                    _variablesDeclared.Add(local);
                }
            }

            base.VisitCatchBlock(catchBlock, ref finallyState);
        }
コード例 #29
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (!analysis.CatchContainsAwait(node))
            {
                return (BoundCatchBlock)base.VisitCatchBlock(node);
            }

            var currentAwaitCatchFrame = this.currentAwaitCatchFrame;
            if (currentAwaitCatchFrame == null)
            {
                currentAwaitCatchFrame = this.currentAwaitCatchFrame = new AwaitCatchFrame(F);
            }

            var catchType = node.ExceptionTypeOpt ?? F.SpecialType(SpecialType.System_Object);
            var catchTemp = F.SynthesizedLocal(catchType);

            var storePending = F.AssignmentExpression(
                        F.Local(currentAwaitCatchFrame.pendingCaughtException),
                        F.Convert(currentAwaitCatchFrame.pendingCaughtException.Type,
                            F.Local(catchTemp)));

            var setPendingCatchNum = F.Assignment(
                            F.Local(currentAwaitCatchFrame.pendingCatch),
                            F.Literal(currentAwaitCatchFrame.handlers.Count + 1));

            //  catch (ExType exTemp)
            //  {
            //      pendingCaughtException = exTemp;
            //      catchNo = X;
            //  }
            BoundCatchBlock catchAndPend;
            ImmutableArray<LocalSymbol> handlerLocals;

            var filterOpt = node.ExceptionFilterOpt;
            if (filterOpt == null)
            {
                // store pending exception 
                // as the first statement in a catch
                catchAndPend = node.Update(
                    catchTemp,
                    F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: null,
                    body: F.Block(
                        F.HiddenSequencePoint(),
                        F.ExpressionStatement(storePending),
                        setPendingCatchNum));

                // catch local lives on the synthetic catch handler block
                handlerLocals = node.LocalOpt == null ?
                                ImmutableArray<LocalSymbol>.Empty :
                                ImmutableArray.Create(node.LocalOpt);
            }
            else
            {
                // catch local moves up into hoisted locals
                // since we might need to access it from both the filter and the catch
                handlerLocals = ImmutableArray<LocalSymbol>.Empty;
                if (node.LocalOpt != null)
                {
                    currentAwaitCatchFrame.HoistLocal(node.LocalOpt, F);
                }

                // store pending exception 
                // as the first expression in a filter
                var sourceOpt = node.ExceptionSourceOpt;
                var rewrittenFilter = (BoundExpression)this.Visit(filterOpt);
                var newFilter = sourceOpt == null ?
                                F.Sequence(
                                    storePending,
                                    rewrittenFilter) :
                                F.Sequence(
                                    storePending,
                                    AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame),
                                    rewrittenFilter);

                catchAndPend = node.Update(
                    catchTemp,
                    F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: newFilter,
                    body: F.Block(
                        F.HiddenSequencePoint(),
                        setPendingCatchNum));
            }

            var handlerStatements = ArrayBuilder<BoundStatement>.GetInstance();

            handlerStatements.Add(F.HiddenSequencePoint());

            if (filterOpt == null)
            {
                var sourceOpt = node.ExceptionSourceOpt;
                if (sourceOpt != null)
                {
                    BoundExpression assignSource = AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame);
                    handlerStatements.Add(F.ExpressionStatement(assignSource));
                }
            }

            handlerStatements.Add((BoundStatement)this.Visit(node.Body));

            var handler = F.Block(
                    handlerLocals,
                    handlerStatements.ToImmutableAndFree()
                );

            currentAwaitCatchFrame.handlers.Add(handler);

            return catchAndPend;
        }
コード例 #30
0
 public override BoundExpression InstrumentCatchClauseFilter(BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory)
 {
     return Previous.InstrumentCatchClauseFilter(original, rewrittenFilter, factory);
 }
コード例 #31
0
ファイル: Instrumenter.cs プロジェクト: Rickinio/roslyn
 public virtual BoundExpression InstrumentCatchClauseFilter(BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory)
 {
     Debug.Assert(!original.WasCompilerGenerated);
     Debug.Assert(original.Syntax.Kind() == SyntaxKind.CatchClause);
     Debug.Assert(((CatchClauseSyntax)original.Syntax).Filter != null);
     Debug.Assert(factory != null);
     return rewrittenFilter;
 }
コード例 #32
0
            public override BoundNode VisitCatchBlock(BoundCatchBlock node)
            {
                var locals = node.Locals;

                if (locals.IsEmpty)
                {
                    return base.VisitCatchBlock(node);
                }

                var previousBlock = PushBlock(node, locals);
                var result = base.VisitCatchBlock(node);
                PopBlock(previousBlock);
                return node;
            }
コード例 #33
0
            public override BoundNode VisitCatchBlock(BoundCatchBlock node)
            {
                var origSeenAwait = _seenAwait;
                _seenAwait = false;

                var result = base.VisitCatchBlock(node);

                if (_seenAwait)
                {
                    var awaitContainingCatches = _awaitContainingCatches;
                    if (awaitContainingCatches == null)
                    {
                        _awaitContainingCatches = awaitContainingCatches = new HashSet<BoundCatchBlock>();
                    }

                    _awaitContainingCatches.Add(node);
                }

                _seenAwait |= origSeenAwait;
                return result;
            }
コード例 #34
0
 /// <summary>
 /// Returns true if a catch contains awaits
 /// </summary>
 internal bool CatchContainsAwait(BoundCatchBlock node)
 {
     return _awaitContainingCatches != null && _awaitContainingCatches.Contains(node);
 }
コード例 #35
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (!_analysis.CatchContainsAwait(node))
            {
                var origCurrentAwaitCatchFrame = _currentAwaitCatchFrame;
                _currentAwaitCatchFrame = null;

                var result = base.VisitCatchBlock(node);
                _currentAwaitCatchFrame = origCurrentAwaitCatchFrame;
                return result;
            }

            var currentAwaitCatchFrame = _currentAwaitCatchFrame;
            if (currentAwaitCatchFrame == null)
            {
                Debug.Assert(node.Syntax.IsKind(SyntaxKind.CatchClause));
                var tryStatementSyntax = (TryStatementSyntax)node.Syntax.Parent;

                currentAwaitCatchFrame = _currentAwaitCatchFrame = new AwaitCatchFrame(_F, tryStatementSyntax);
            }

            var catchType = node.ExceptionTypeOpt ?? _F.SpecialType(SpecialType.System_Object);
            var catchTemp = _F.SynthesizedLocal(catchType);

            var storePending = _F.AssignmentExpression(
                        _F.Local(currentAwaitCatchFrame.pendingCaughtException),
                        _F.Convert(currentAwaitCatchFrame.pendingCaughtException.Type,
                            _F.Local(catchTemp)));

            var setPendingCatchNum = _F.Assignment(
                            _F.Local(currentAwaitCatchFrame.pendingCatch),
                            _F.Literal(currentAwaitCatchFrame.handlers.Count + 1));

            //  catch (ExType exTemp)
            //  {
            //      pendingCaughtException = exTemp;
            //      catchNo = X;
            //  }
            BoundCatchBlock catchAndPend;
            var handlerLocals = ImmutableArray<LocalSymbol>.Empty;

            var filterOpt = node.ExceptionFilterOpt;
            if (filterOpt == null)
            {
                // store pending exception 
                // as the first statement in a catch
                catchAndPend = node.Update(
                    catchTemp,
                    _F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: null,
                    body: _F.Block(
                        _F.HiddenSequencePoint(),
                        _F.ExpressionStatement(storePending),
                        setPendingCatchNum),
                    isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll);

                // catch locals live on the synthetic catch handler block
                if ((object)node.LocalOpt != null)
                {
                    handlerLocals = ImmutableArray.Create(node.LocalOpt);
                }
            }
            else
            {
                // catch locals move up into hoisted locals
                // since we might need to access them from both the filter and the catch
                if ((object)node.LocalOpt != null)
                {
                    currentAwaitCatchFrame.HoistLocal(node.LocalOpt, _F);
                }

                // store pending exception 
                // as the first expression in a filter
                var sourceOpt = node.ExceptionSourceOpt;
                var rewrittenFilter = (BoundExpression)this.Visit(filterOpt);
                var newFilter = sourceOpt == null ?
                                _F.Sequence(
                                    storePending,
                                    rewrittenFilter) :
                                _F.Sequence(
                                    storePending,
                                    AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame),
                                    rewrittenFilter);

                catchAndPend = node.Update(
                    catchTemp,
                    _F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: newFilter,
                    body: _F.Block(
                        _F.HiddenSequencePoint(),
                        setPendingCatchNum),
                    isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll);
            }

            var handlerStatements = ArrayBuilder<BoundStatement>.GetInstance();

            handlerStatements.Add(_F.HiddenSequencePoint());

            if (filterOpt == null)
            {
                var sourceOpt = node.ExceptionSourceOpt;
                if (sourceOpt != null)
                {
                    BoundExpression assignSource = AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame);
                    handlerStatements.Add(_F.ExpressionStatement(assignSource));
                }
            }

            handlerStatements.Add((BoundStatement)this.Visit(node.Body));

            var handler = _F.Block(
                    handlerLocals,
                    ImmutableArray<LocalFunctionSymbol>.Empty,
                    handlerStatements.ToImmutableAndFree()
                );

            currentAwaitCatchFrame.handlers.Add(handler);

            return catchAndPend;
        }
コード例 #36
0
 public override BoundNode VisitCatchBlock(BoundCatchBlock node)
 {
     AddVariables(node.Locals);
     return(base.VisitCatchBlock(node));
 }
コード例 #37
0
            public override BoundNode VisitCatchBlock(BoundCatchBlock node)
            {
                var local = node.LocalOpt;

                if ((object)local == null)
                {
                    return base.VisitCatchBlock(node);
                }

                var previousBlock = PushBlock(node, ImmutableArray.Create(local));
                var result = base.VisitCatchBlock(node);
                PopBlock(previousBlock);
                return node;
            }
コード例 #38
0
        public override BoundNode VisitCatchBlock(BoundCatchBlock node)
        {
            if (!_analysis.CatchContainsAwait(node))
            {
                var origCurrentAwaitCatchFrame = _currentAwaitCatchFrame;
                _currentAwaitCatchFrame = null;

                var result = base.VisitCatchBlock(node);
                _currentAwaitCatchFrame = origCurrentAwaitCatchFrame;
                return(result);
            }

            var currentAwaitCatchFrame = _currentAwaitCatchFrame;

            if (currentAwaitCatchFrame == null)
            {
                Debug.Assert(node.Syntax.IsKind(SyntaxKind.CatchClause));
                var tryStatementSyntax = (TryStatementSyntax)node.Syntax.Parent;

                currentAwaitCatchFrame = _currentAwaitCatchFrame = new AwaitCatchFrame(_F, tryStatementSyntax);
            }

            var catchType = node.ExceptionTypeOpt ?? _F.SpecialType(SpecialType.System_Object);
            var catchTemp = _F.SynthesizedLocal(catchType);

            var storePending = _F.AssignmentExpression(
                _F.Local(currentAwaitCatchFrame.pendingCaughtException),
                _F.Convert(currentAwaitCatchFrame.pendingCaughtException.Type.TypeSymbol,
                           _F.Local(catchTemp)));

            var setPendingCatchNum = _F.Assignment(
                _F.Local(currentAwaitCatchFrame.pendingCatch),
                _F.Literal(currentAwaitCatchFrame.handlers.Count + 1));

            //  catch (ExType exTemp)
            //  {
            //      pendingCaughtException = exTemp;
            //      catchNo = X;
            //  }
            BoundCatchBlock catchAndPend;
            ImmutableArray <LocalSymbol> handlerLocals;

            var filterOpt = node.ExceptionFilterOpt;

            if (filterOpt == null)
            {
                // store pending exception
                // as the first statement in a catch
                catchAndPend = node.Update(
                    ImmutableArray.Create(catchTemp),
                    _F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: null,
                    body: _F.Block(
                        _F.HiddenSequencePoint(),
                        _F.ExpressionStatement(storePending),
                        setPendingCatchNum),
                    isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll);

                // catch locals live on the synthetic catch handler block
                handlerLocals = node.Locals;
            }
            else
            {
                handlerLocals = ImmutableArray <LocalSymbol> .Empty;

                // catch locals move up into hoisted locals
                // since we might need to access them from both the filter and the catch
                foreach (var local in node.Locals)
                {
                    currentAwaitCatchFrame.HoistLocal(local, _F);
                }

                // store pending exception
                // as the first expression in a filter
                var sourceOpt       = node.ExceptionSourceOpt;
                var rewrittenFilter = (BoundExpression)this.Visit(filterOpt);
                var newFilter       = sourceOpt == null?
                                      _F.MakeSequence(
                    storePending,
                    rewrittenFilter) :
                                          _F.MakeSequence(
                                              storePending,
                                              AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame),
                                              rewrittenFilter);

                catchAndPend = node.Update(
                    ImmutableArray.Create(catchTemp),
                    _F.Local(catchTemp),
                    catchType,
                    exceptionFilterOpt: newFilter,
                    body: _F.Block(
                        _F.HiddenSequencePoint(),
                        setPendingCatchNum),
                    isSynthesizedAsyncCatchAll: node.IsSynthesizedAsyncCatchAll);
            }

            var handlerStatements = ArrayBuilder <BoundStatement> .GetInstance();

            handlerStatements.Add(_F.HiddenSequencePoint());

            if (filterOpt == null)
            {
                var sourceOpt = node.ExceptionSourceOpt;
                if (sourceOpt != null)
                {
                    BoundExpression assignSource = AssignCatchSource((BoundExpression)this.Visit(sourceOpt), currentAwaitCatchFrame);
                    handlerStatements.Add(_F.ExpressionStatement(assignSource));
                }
            }

            handlerStatements.Add((BoundStatement)this.Visit(node.Body));

            var handler = _F.Block(
                handlerLocals,
                handlerStatements.ToImmutableAndFree()
                );

            currentAwaitCatchFrame.handlers.Add(handler);

            return(catchAndPend);
        }
コード例 #39
0
ファイル: DebugInfoInjector.cs プロジェクト: xeronith/roslyn
        public override BoundExpression InstrumentCatchClauseFilter(BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory)
        {
            rewrittenFilter = base.InstrumentCatchClauseFilter(original, rewrittenFilter, factory);

            // EnC: We need to insert a hidden sequence point to handle function remapping in case 
            // the containing method is edited while methods invoked in the condition are being executed.
            CatchFilterClauseSyntax filterClause = ((CatchClauseSyntax)original.Syntax).Filter;
            return AddConditionSequencePoint(new BoundSequencePointExpression(filterClause, rewrittenFilter, rewrittenFilter.Type), filterClause, factory);
        }
コード例 #40
0
        protected override void VisitCatchBlock(BoundCatchBlock catchBlock, ref LocalState finallyState)
        {
            if (IsInside)
            {
                if ((object)catchBlock.LocalOpt != null)
                {
                    variablesDeclared.Add(catchBlock.LocalOpt);
                }
            }

            base.VisitCatchBlock(catchBlock, ref finallyState);
        }
コード例 #41
0
 internal BoundExpression AddConditionSequencePoint(BoundExpression condition, BoundCatchBlock containingCatchWithFilter)
 {
     Debug.Assert(containingCatchWithFilter.ExceptionFilterOpt.Syntax.IsKind(SyntaxKind.CatchFilterClause));
     return(AddConditionSequencePoint(condition, containingCatchWithFilter.ExceptionFilterOpt.Syntax, containingCatchWithFilter.WasCompilerGenerated));
 }