internal override void Visit(ExceptionHandlerNode node) { }
protected static void CreateCatchHandlerEntryBlock(ProgramState state, ExceptionHandlerNode handlerNode, CfgNode handlerEntryPredecessor, Identifier exceptionIdentifier) { (var trueBranch, var falseBranch) = CreateExceptionTypeCheckBranchNodes( state, handlerNode.ExceptionHandler, exceptionIdentifier); handlerEntryPredecessor.Successors.Add(trueBranch); handlerEntryPredecessor.Successors.Add(falseBranch); if (!state.ExceptionHandlerToCatchVarNode.ContainsKey(handlerNode.ExceptionHandler)) { state.ExceptionHandlerToCatchVarNode[handlerNode.ExceptionHandler] = CreateLoadCatchVarNode(state, handlerNode.ExceptionHandler); // The CIL specification dictates that the exception object is on top of // the stack when the catch handler is entered; the first instruction of // the catch handler will handle the object pushed onto the stack. state.PushExpr(new VarExpression(exceptionIdentifier), new Tptr(Tptr.PtrKind.Pk_pointer, new Tstruct("System.Object"))); state.PushInstruction( handlerNode.ExceptionHandler.HandlerStart, state.ExceptionHandlerToCatchVarNode[handlerNode.ExceptionHandler].node); } (var loadCatchVarNode, _) = GetHandlerCatchVarNode( state, handlerNode.ExceptionHandler); trueBranch.Successors.Add(loadCatchVarNode); if (handlerNode.NextCatchBlock != null) { // Continues translation with catch handler's first instruction from // the handler's catch variable load node. CreateCatchHandlerEntryBlock(state, handlerNode.NextCatchBlock, falseBranch, exceptionIdentifier); } // Last catch handler of set; need to route control flow through the false // exception type-matching node. else { if (handlerNode.FinallyBlock != null) { var finallyBranchNode = CreateFinallyExceptionBranchNode( state, handlerNode.ExceptionHandler); falseBranch.Successors .Add(finallyBranchNode); (var finallyLoadCatchVar, _) = GetHandlerCatchVarNode( state, handlerNode.FinallyBlock); finallyBranchNode.Successors.Add(finallyLoadCatchVar); } else { var returnVariable = new LvarExpression( new LocalVariable(Identifier.ReturnIdentifier, state.Method)); var retType = state.Method.ReturnType.GetElementType(); var retInstr = new Store( returnVariable, new ExnExpression(new VarExpression(exceptionIdentifier)), Typ.FromTypeReference(retType), GetHandlerStartLocation(state, handlerNode.ExceptionHandler)); falseBranch.Instructions .Add(retInstr); falseBranch.Successors .Add(state.ProcDesc.ExceptionSinkNode); } } }