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)); }
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); }
public override BoundNode VisitCatchBlock(BoundCatchBlock node) { AddAll(node.Locals); base.VisitCatchBlock(node); RemoveAll(node.Locals); return(null); }
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); }
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); }
public override BoundExpression InstrumentCatchClauseFilter( BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory ) { return(Previous.InstrumentCatchClauseFilter(original, rewrittenFilter, factory)); }
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)); }
public override BoundNode VisitCatchBlock(BoundCatchBlock node) { var oldScope = _currentScope; _currentScope = CreateOrReuseScope(node, node.Locals); var result = base.VisitCatchBlock(node); _currentScope = oldScope; return(result); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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())); } }
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); } } }
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); }
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); }
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)); }
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); } }
internal BoundExpression AddConditionSequencePoint(BoundExpression condition, BoundCatchBlock containingCatchWithFilter) { Debug.Assert(containingCatchWithFilter.ExceptionFilterOpt.Syntax.IsKind(SyntaxKind.CatchFilterClause)); return AddConditionSequencePoint(condition, containingCatchWithFilter.ExceptionFilterOpt.Syntax, containingCatchWithFilter.WasCompilerGenerated); }
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); }
public override BoundNode VisitCatchBlock(BoundCatchBlock node) { AddVariable(node.LocalOpt); return base.VisitCatchBlock(node); }
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); }
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)); }
/// <summary> /// Returns true if a catch contains awaits /// </summary> internal bool CatchContainsAwait(BoundCatchBlock node) { return(_awaitContainingCatches != null && _awaitContainingCatches.Contains(node)); }
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; }
public override BoundExpression InstrumentCatchClauseFilter(BoundCatchBlock original, BoundExpression rewrittenFilter, SyntheticBoundNodeFactory factory) { return Previous.InstrumentCatchClauseFilter(original, rewrittenFilter, factory); }
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; }
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; }
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; }
/// <summary> /// Returns true if a catch contains awaits /// </summary> internal bool CatchContainsAwait(BoundCatchBlock node) { return _awaitContainingCatches != null && _awaitContainingCatches.Contains(node); }
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; }
public override BoundNode VisitCatchBlock(BoundCatchBlock node) { AddVariables(node.Locals); return(base.VisitCatchBlock(node)); }
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; }
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); }
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); }
internal BoundExpression AddConditionSequencePoint(BoundExpression condition, BoundCatchBlock containingCatchWithFilter) { Debug.Assert(containingCatchWithFilter.ExceptionFilterOpt.Syntax.IsKind(SyntaxKind.CatchFilterClause)); return(AddConditionSequencePoint(condition, containingCatchWithFilter.ExceptionFilterOpt.Syntax, containingCatchWithFilter.WasCompilerGenerated)); }