Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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));
        }