private void CreateExceptionHandlers(CilCompilationUnit unit, CilInstructionCollection result) { foreach (var subGraph in unit.ControlFlowGraph.SubGraphs) { var ehFrame = (EHFrame)subGraph.UserData[EHFrame.EHFrameProperty]; ExceptionHandlerType type; switch (ehFrame.Type) { case EHType.CATCH: type = ExceptionHandlerType.Exception; break; case EHType.FILTER: type = ExceptionHandlerType.Filter; break; case EHType.FAULT: type = ExceptionHandlerType.Fault; break; case EHType.FINALLY: type = ExceptionHandlerType.Finally; break; default: throw new ArgumentOutOfRangeException(); } // Find first and last nodes of try block. var tryBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.TryBlockProperty]; var(tryStartNode, tryEndNode) = FindMinMaxNodes(tryBody); // Find first and last nodes of handler block. var handlerBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.HandlerBlockProperty]; var(handlerStartNode, handlerEndNode) = FindMinMaxNodes(handlerBody); // Create handler. var handler = new ExceptionHandler(type) { TryStart = _blockEntries[tryStartNode], TryEnd = result.GetByOffset(_blockExits[tryEndNode].Offset + _blockExits[tryEndNode].Size) ?? throw new CilCodeGeneratorException( $"Could not infer end of try block in {_context.MethodBody.Method.Name}."), HandlerStart = _blockEntries[handlerStartNode], HandlerEnd = result.GetByOffset(_blockExits[handlerEndNode].Offset + _blockExits[handlerEndNode].Size) ?? throw new CilCodeGeneratorException( $"Could not infer end of handler block in {_context.MethodBody.Method.Name}."), CatchType = ehFrame.CatchType }; _context.ExceptionHandlers.Add(ehFrame, handler); } }
private ICilLabel GetHandlerEndLabel(CilInstructionCollection result, Node endNode, string type) { var instruction = result.GetByOffset(_blockExits[endNode].Offset + _blockExits[endNode].Size); if (instruction is null) { throw new CilCodeGeneratorException( $"Could not infer end of {type} block in {_context.MethodBody.Owner.Name}."); } return(new CilInstructionLabel(instruction)); }