public void FirstBlockWithNullPrologueShouldResultInFirstBlockOfHandler() { var handler = new HandlerBlock <int>(); handler.Contents.Blocks.Add(new BasicBlock <int>()); Assert.Same(handler.Contents.Blocks[0], handler.GetFirstBlock()); }
public void LastBlockWithNullEpilogueShouldResultInLastBlockOfHandler() { var handler = new HandlerBlock <int>(); handler.Contents.Blocks.Add(new BasicBlock <int>()); handler.Contents.Blocks.Add(new BasicBlock <int>()); handler.Contents.Blocks.Add(new BasicBlock <int>()); Assert.Same(handler.Contents.Blocks[^ 1], handler.GetLastBlock());
public void FirstBlockWithEmptyContentAndNonEmptyEpilogueShouldResultInFirstBlockOfEpilogue() { var handler = new HandlerBlock <int>(); handler.Epilogue = new ScopeBlock <int>(); handler.Epilogue.Blocks.Add(new BasicBlock <int>()); Assert.Same(handler.Epilogue.Blocks[0], handler.GetFirstBlock()); }
void doHandlerBlock(HandlerBlock handlerBlock) { stateStack.Push(new BlockState(handlerBlock)); processBaseBlocks(handlerBlock.BaseBlocks, (block) => { return(block.LastInstr.OpCode == OpCodes.Endfinally || block.LastInstr.OpCode == OpCodes.Leave || block.LastInstr.OpCode == OpCodes.Leave_S); }); stateStack.Pop(); }
private static void EnterExceptionHandlerSubRegion <TInstruction>( IndexableStack <ScopeInfo <TInstruction> > scopeStack, ExceptionHandlerRegion <TInstruction> parentRegion, IControlFlowRegion <TInstruction> enteredRegion) { IBlock <TInstruction> enteredBlock; IControlFlowRegion <TInstruction> enteredSubRegion; if (!(scopeStack.Peek().Block is ExceptionHandlerBlock <TInstruction> ehBlock)) { throw new InvalidOperationException("The parent scope is not an exception handler scope."); } // Did we enter the protected region, or one of the handler regions? if (parentRegion.ProtectedRegion == enteredRegion) { // We entered the protected region. enteredBlock = ehBlock.ProtectedBlock; enteredSubRegion = parentRegion.ProtectedRegion; } else { // We entered a handler region. var handlerRegion = parentRegion.Handlers.First(r => r == enteredRegion); var handlerBlock = new HandlerBlock <TInstruction> { Tag = handlerRegion.Tag }; enteredBlock = handlerBlock; enteredSubRegion = handlerRegion; ehBlock.Handlers.Add(handlerBlock); } // Sanity check: If the entered subregion's parent is the exception handler region but the region // isn't a protected, prologue, epilogue nor one of the handler regions, that would mean that // something went *seriously* wrong. if (enteredSubRegion is null) { throw new InvalidOperationException( "Entered subregion of exception handler doesn't belong to any of its regions!?"); } // Push the entered scope. scopeStack.Push(new ScopeInfo <TInstruction>(enteredSubRegion, enteredBlock)); }
private ExceptionHandler GetExceptionHandler(TryBlock tryBlock, HandlerBlock handlerBlock) { var tryStart = tryBlock.FirstBlock.First(); var tryEnd = GetNextBasicBlock(tryBlock.LastBlock.Last()) ?? throw new InvalidOperationException(); var filterStart = handlerBlock.Filter?.FirstBlock.First(); var handlerStart = handlerBlock.FirstBlock.First(); var handlerEnd = GetNextBasicBlock(handlerBlock.LastBlock.Last()); return(new ExceptionHandler() { TryStart = GetFirstInstruction(tryStart), TryEnd = GetFirstInstruction(tryEnd), HandlerStart = GetFirstInstruction(handlerStart), HandlerEnd = !(handlerEnd is null) ? GetFirstInstruction(handlerEnd) : null, FilterStart = !(filterStart is null) ? GetFirstInstruction(filterStart) : null, CatchType = handlerBlock.CatchType, HandlerType = GetHandlerType(handlerBlock) });
private ExceptionHandler GetExceptionHandler(Instruction tryStart, Instruction?tryEnd, ScopeBlock?filterBlock, HandlerBlock handlerBlock) { var filterStart = filterBlock?.FirstBlock.First(); var handlerStart = handlerBlock.FirstBlock.First(); var handlerEnd = GetNextBasicBlock(handlerBlock.LastBlock.Last()); return(new ExceptionHandler() { TryStart = tryStart, TryEnd = tryEnd, HandlerStart = GetFirstInstruction(handlerStart), HandlerEnd = !(handlerEnd is null) ? GetFirstInstruction(handlerEnd) : null, FilterStart = !(filterStart is null) ? GetFirstInstruction(filterStart) : null, CatchType = handlerBlock.CatchType, HandlerType = GetHandlerType(filterBlock, handlerBlock) });
void doHandlerBlock(HandlerBlock handlerBlock) { stateStack.Push(new BlockState(handlerBlock)); processBaseBlocks(handlerBlock.BaseBlocks, (block) => { return block.LastInstr.OpCode == OpCodes.Endfinally || block.LastInstr.OpCode == OpCodes.Leave || block.LastInstr.OpCode == OpCodes.Leave_S; }); stateStack.Pop(); }
/// <inheritdoc /> public virtual void ExitHandlerContents(HandlerBlock <TInstruction> block) { }
/// <inheritdoc /> public virtual void ExitEpilogueBlock(HandlerBlock <TInstruction> block) { }
/// <inheritdoc /> public virtual void EnterPrologueBlock(HandlerBlock <TInstruction> block) { }