private IEnumerable <Block> GetFinallyBlocks(FinallyNode finallyNode) { List <Block> blocks = new List <Block>(); blocks.Add(finallyNode.Block); blocks.AddRange(GetBlocks(finallyNode.Block.Statements)); return(blocks); }
public FinallyBuilder(FinallyNode finallynode) { node = finallynode; DotDefinition = new List <IDotElement>(); CreateNode(); CreateEndNode(); CreateEdgeToFirstChildren(); CreateEndTryEdge(); }
protected void GenInterStatementBreak(CompileContext compileContext, Label lbl, baseNode destNode) { tryStatementNode FinallyNode; bool bNeedLeave = this.NeedLeave(destNode, out FinallyNode); if (FinallyNode != null) { FinallyNode.GenFinallyForward(compileContext, lbl, destNode, bNeedLeave); } else { compileContext.gen.Emit(bNeedLeave ? OpCodes.Leave : OpCodes.Br, lbl); } }
override protected void ParseExceptionHandlerEntry(bool smallSection) { int dataSize = this.reader.tables.GetByte(); int n = (int)(ushort)this.reader.tables.GetInt16(); if (smallSection) n = dataSize / 12; else n = (dataSize + (n << 8)) / 24; for (int i = 0; i < n; i++) { int flags, tryOffset, tryLength, handlerOffset, handlerLength, tokenOrOffset; if (smallSection) { flags = this.reader.tables.GetInt16(); tryOffset = this.reader.tables.GetUInt16(); tryLength = this.reader.tables.GetByte(); handlerOffset = this.reader.tables.GetUInt16(); handlerLength = this.reader.tables.GetByte(); } else { flags = this.reader.tables.GetInt32(); tryOffset = this.reader.tables.GetInt32(); tryLength = this.reader.tables.GetInt32(); handlerOffset = this.reader.tables.GetInt32(); handlerLength = this.reader.tables.GetInt32(); } tokenOrOffset = this.reader.tables.GetInt32(); Block tryStartBlock = Reader.GetOrCreateBlock(this.blockMap, tryOffset); Block blockAfterTryEnd = Reader.GetOrCreateBlock(this.blockMap, tryOffset + tryLength); Block handlerStartBlock = Reader.GetOrCreateBlock(this.blockMap, handlerOffset); Block blockAfterHandlerEnd = Reader.GetOrCreateBlock(this.blockMap, handlerOffset + handlerLength); List<TryNode> tryList = null; if (!this.tryMap.TryGetValue(tryStartBlock, out tryList)) { this.tryMap[tryStartBlock] = tryList = new List<TryNode>(); } TryNode currentTry = null; int tryEnd = tryOffset + tryLength; foreach (TryNode t in tryList) { if (t.tryEnd == tryEnd) { currentTry = t; break; } } if (currentTry == null) { currentTry = new TryNode(); currentTry.tryEnd = tryEnd; tryList.Add(currentTry); } int handlerEnd = handlerOffset + handlerLength; if (currentTry.handlersEnd < handlerEnd) currentTry.handlersEnd = handlerEnd; Debug.Assert((int)flags != 3); Debug.Assert((int)flags < 5); switch (flags) { case 0x00: // for a catch handler, tokenOrOffset represents // the metadata token of the handler type. handlerOffset // is the literal offset for the catch block int pos = this.reader.tables.GetCurrentPosition(); TypeNode filterType = (TypeNode)this.reader.GetMemberFromToken(tokenOrOffset); this.reader.tables.SetCurrentPosition(pos); string variableName = "$exception" + this.handlerMap.Count.ToString(CultureInfo.InvariantCulture); StackVariable exception = new StackVariable(filterType, variableName); CatchNode c = new CatchNode(handlerStartBlock, exception, filterType); c.handlerEnd = handlerEnd; currentTry.Catchers.Add(c); this.handlerMap[handlerOffset] = exception; break; case 0x01: // for a filter, tokenOrOffset represents the IL offset // of the filter block. handlerOffset represents // the IL offset of the associated catch handler Block filterExpression = Reader.GetOrCreateBlock(blockMap, tokenOrOffset); variableName = "$exception" + this.handlerMap.Count.ToString(CultureInfo.InvariantCulture); exception = new StackVariable(CoreSystemTypes.Object, variableName); Filter filter = new Filter(filterExpression, exception); filter.handlerEnd = handlerOffset; c = new CatchNode(handlerStartBlock, exception, null, filter); c.handlerEnd = handlerEnd; currentTry.Catchers.Add(c); // note that handlerOffset would not be correct here! this.handlerMap[tokenOrOffset] = exception; break; case 0x02: FinallyNode f = new FinallyNode(handlerStartBlock); f.handlerEnd = handlerEnd; currentTry.Finally = f; break; case 0x04: FaultHandler fh = new FaultHandler(handlerStartBlock); fh.handlerEnd = handlerEnd; currentTry.FaultHandler = fh; break; } } }