/// <summary> /// Generates the try/finally construct that is represented by the specifed exception handler info and attaches it to the logical tree. /// </summary> /// <param name="handlerInfo"></param> private void GenerateTryFinallyHandler(YieldExceptionHandlerInfo handlerInfo) { finallyBlocks = new HashSet <ILogicalConstruct>(); entryOfTry = GetStateBeginBlockConstruct(handlerInfo.TryStates); BuildTryBody(handlerInfo); BlockLogicalConstruct newFinally; if (handlerInfo.HandlerType == YieldExceptionHandlerType.Method) { if (newFinallyBody == null) { throw new Exception("Could not determine the end ot the try block"); } RemoveExcessNodesFromTheTryBlock(); ProcessFinallyNodes(); newFinally = new BlockLogicalConstruct(newFinallyBody, new ILogicalConstruct[] { newFinallyBody }); } else { newFinally = GenerateFinallyBlock(); } BlockLogicalConstruct newTry = new BlockLogicalConstruct(entryOfTry, newTryBody); TryFinallyLogicalConstruct newTryFinallyConstruct = new TryFinallyLogicalConstruct(newTry, newFinally); createdConstructsToIntervalMap[newTryFinallyConstruct] = handlerInfo; CleanUpOrderedNodes(newTryFinallyConstruct); }
private void GenerateTryFinallyHandler(YieldExceptionHandlerInfo handlerInfo) { this.finallyBlocks = new HashSet <ILogicalConstruct>(); this.entryOfTry = this.GetStateBeginBlockConstruct(handlerInfo.get_TryStates()); this.BuildTryBody(handlerInfo); if (handlerInfo.get_HandlerType() != YieldExceptionHandlerType.Method) { V_0 = this.GenerateFinallyBlock(); } else { if (this.newFinallyBody == null) { throw new Exception("Could not determine the end ot the try block"); } this.RemoveExcessNodesFromTheTryBlock(); this.ProcessFinallyNodes(); stackVariable31 = this.newFinallyBody; stackVariable33 = new ILogicalConstruct[1]; stackVariable33[0] = this.newFinallyBody; V_0 = new BlockLogicalConstruct(stackVariable31, stackVariable33); } V_1 = new TryFinallyLogicalConstruct(new BlockLogicalConstruct(this.entryOfTry, this.newTryBody), V_0); this.createdConstructsToIntervalMap.set_Item(V_1, handlerInfo); this.CleanUpOrderedNodes(V_1); return; }
private void ProcessGotoFlowConstructs(BlockLogicalConstruct theConstruct) { ILogicalConstruct[] sortedChildren = new ILogicalConstruct[theConstruct.Children.Count]; int index = 0; foreach (ILogicalConstruct child in theConstruct.Children) { sortedChildren[index++] = child; } Array.Sort <ISingleEntrySubGraph>(sortedChildren); HashSet <ILogicalConstruct> usedAsFollow = new HashSet <ILogicalConstruct>(); foreach (ILogicalConstruct currentChild in sortedChildren) { if (visitedConstructs.Add(currentChild)) { if (visitedConstructs.Contains(currentChild.FollowNode) || !usedAsFollow.Add(currentChild.FollowNode)) { currentChild.CFGFollowNode = null; } ProcessLogicalConstruct(currentChild); } } }
private BlockLogicalConstruct DetermineTheBlock(BlockLogicalConstruct theBlock) { if (theBlock.get_Entry() as TryFaultLogicalConstruct == null || theBlock.get_Children().get_Count() > 2) { return(theBlock); } return((theBlock.get_Entry() as TryFaultLogicalConstruct).get_Try()); }
/// <summary> /// Determines the block logical construct in which the algorithm, for recreating the removed try/finally constructs, will be executed. /// </summary> /// <param name="theBlock"></param> /// <returns></returns> private BlockLogicalConstruct DetermineTheBlock(BlockLogicalConstruct theBlock) { if(theBlock.Entry is TryFaultLogicalConstruct && theBlock.Children.Count <= 2) //the try/fault construct and a return block { return (theBlock.Entry as TryFaultLogicalConstruct).Try; } else { return theBlock; } }
/// <summary> /// Determines the block logical construct in which the algorithm, for recreating the removed try/finally constructs, will be executed. /// </summary> /// <param name="theBlock"></param> /// <returns></returns> private BlockLogicalConstruct DetermineTheBlock(BlockLogicalConstruct theBlock) { if (theBlock.Entry is TryFaultLogicalConstruct && theBlock.Children.Count <= 2) //the try/fault construct and a return block { return((theBlock.Entry as TryFaultLogicalConstruct).Try); } else { return(theBlock); } }
/// <summary> /// Initializes the block logical construct representing the method body. /// </summary> private void InitializeTheBlock() { MapBlocks(); CFGBlockLogicalConstruct entry = logicalBuilderContext.CFGBlockToLogicalConstructMap[logicalBuilderContext.CFG.Blocks[0]][0]; HashSet <ILogicalConstruct> blockContents = new HashSet <ILogicalConstruct>(); foreach (CFGBlockLogicalConstruct[] cfgBlocks in logicalBuilderContext.CFGBlockToLogicalConstructMap.Values) { blockContents.UnionWith(cfgBlocks); } theBlockLogicalConstruct = new BlockLogicalConstruct(entry, blockContents); }
/// <summary> /// Initializes the block logical construct representing the method body. /// </summary> private void InitializeTheBlock() { MapBlocks(); CFGBlockLogicalConstruct entry = logicalBuilderContext.CFGBlockToLogicalConstructMap[logicalBuilderContext.CFG.Blocks[0]][0]; HashSet<ILogicalConstruct> blockContents = new HashSet<ILogicalConstruct>(); foreach (CFGBlockLogicalConstruct[] cfgBlocks in logicalBuilderContext.CFGBlockToLogicalConstructMap.Values) { blockContents.UnionWith(cfgBlocks); } theBlockLogicalConstruct = new BlockLogicalConstruct(entry, blockContents); }
internal MethodSpecificContext(DecompilationAnalysisResults analysisResults, YieldData yieldData, AsyncData asyncData, bool isMethodBodyChanged, Dictionary<string, Statement> gotoLabels, List<GotoStatement> gotoStatements, StackUsageData stackData, bool isBaseConstructorInvokingConstructor, bool enableEventAnalysis, MethodBody body, Collection<VariableDefinition> variables, ControlFlowGraph controlFlowGraph, ExpressionDecompilerData expressions, BlockLogicalConstruct logicalConstructsTree, LogicalFlowBuilderContext logicalConstructsContext, MethodInvocationExpression ctorInvokeExpression, Dictionary<Statement, ILogicalConstruct> statementToLogicalConstruct, Dictionary<ILogicalConstruct, List<Statement>> logicalConstructToStatements, Dictionary<VariableDefinition, string> variableDefinitionToNameMap, HashSet<string> variableNamesCollection, Dictionary<ParameterDefinition, string> parameterDefinitionToNameMap, HashSet<VariableDefinition> variablesToRename, Dictionary<FieldDefinition, Expression> fieldToExpression, int lambdaVariablesCount, Dictionary<VariableDefinition, AssignmentType> variableAssignmentData, List<ParameterDefinition> outParametersToAssign, bool isDestructor, BlockStatement destructorStatements, HashSet<VariableDefinition> undeclaredLinqVariables, Dictionary<VariableReference, Dictionary<FieldDefinition, Expression>> closureVariableToFieldValue, HashSet<VariableDefinition> variablesToNotDeclare) { this.AnalysisResults = analysisResults; this.YieldData = yieldData; this.AsyncData = asyncData; this.IsMethodBodyChanged = isMethodBodyChanged; this.GotoLabels = gotoLabels; this.GotoStatements = gotoStatements; this.StackData = stackData; this.IsBaseConstructorInvokingConstructor = isBaseConstructorInvokingConstructor; this.EnableEventAnalysis = enableEventAnalysis; this.Body = body; this.Variables = variables; this.ControlFlowGraph = controlFlowGraph; this.Expressions = expressions; this.LogicalConstructsTree = logicalConstructsTree; this.LogicalConstructsContext = logicalConstructsContext; this.CtorInvokeExpression = ctorInvokeExpression; this.StatementToLogicalConstruct = statementToLogicalConstruct; this.LogicalConstructToStatements = logicalConstructToStatements; this.VariableDefinitionToNameMap = variableDefinitionToNameMap; this.VariableNamesCollection = variableNamesCollection; this.ParameterDefinitionToNameMap = parameterDefinitionToNameMap; this.VariablesToRename = variablesToRename; this.FieldToExpression = fieldToExpression; this.LambdaVariablesCount = lambdaVariablesCount; this.VariableAssignmentData = variableAssignmentData; this.OutParametersToAssign = outParametersToAssign; this.IsDestructor = isDestructor; this.DestructorStatements = destructorStatements; this.UndeclaredLinqVariables = undeclaredLinqVariables; this.ClosureVariableToFieldValue = closureVariableToFieldValue; this.VariablesToNotDeclare = variablesToNotDeclare; }
/// <summary> /// Rebuilds the removed try/finally constructs, using the yield data from the decompilation context. /// </summary> /// <param name="theBlock"></param> public void BuildGuardedBlocks(BlockLogicalConstruct theBlock) { if (methodContext.YieldData == null) { return; } this.theBlock = DetermineTheBlock(theBlock); this.stateFieldRef = methodContext.YieldData.FieldsInfo.StateHolderField; YieldExceptionHandlerInfo[] handlerInfoArray = methodContext.YieldData.ExceptionHandlers; Array.Sort(handlerInfoArray); //The order ensures that if we have 2 or more nested handlers, the most inner will be first, then the second most inner, etc. GetOrderedCFGNodes(); foreach (YieldExceptionHandlerInfo handlerInfo in handlerInfoArray) { GenerateTryFinallyHandler(handlerInfo); } }
/// <summary> /// Rebuilds the removed try/finally constructs, using the yield data from the decompilation context. /// </summary> /// <param name="theBlock"></param> public void BuildGuardedBlocks(BlockLogicalConstruct theBlock) { if (methodContext.YieldData == null) { return; } this.theBlock = DetermineTheBlock(theBlock); this.stateFieldRef = methodContext.YieldData.FieldsInfo.StateHolderField; YieldExceptionHandlerInfo[] handlerInfoArray = methodContext.YieldData.ExceptionHandlers; Array.Sort(handlerInfoArray); //The order ensures that if interval[i] is nested in interval[j] then i < j GetOrderedCFGNodes(); foreach (YieldExceptionHandlerInfo handlerInfo in handlerInfoArray) { GenerateTryFinallyHandler(handlerInfo); } }
/// <summary> /// Rebuilds the removed try/finally constructs, using the yield data from the decompilation context. /// </summary> /// <param name="theBlock"></param> public void BuildGuardedBlocks(BlockLogicalConstruct theBlock) { if(methodContext.YieldData == null) { return; } this.theBlock = DetermineTheBlock(theBlock); this.stateFieldRef = methodContext.YieldData.FieldsInfo.StateHolderField; YieldExceptionHandlerInfo[] handlerInfoArray = methodContext.YieldData.ExceptionHandlers; Array.Sort(handlerInfoArray); //The order ensures that if we have 2 or more nested handlers, the most inner will be first, then the second most inner, etc. GetOrderedCFGNodes(); foreach (YieldExceptionHandlerInfo handlerInfo in handlerInfoArray) { GenerateTryFinallyHandler(handlerInfo); } }
/// <summary> /// Rebuilds the removed try/finally constructs, using the yield data from the decompilation context. /// </summary> /// <param name="theBlock"></param> public void BuildGuardedBlocks(BlockLogicalConstruct theBlock) { if(methodContext.YieldData == null) { return; } this.theBlock = DetermineTheBlock(theBlock); this.stateFieldRef = methodContext.YieldData.FieldsInfo.StateHolderField; YieldExceptionHandlerInfo[] handlerInfoArray = methodContext.YieldData.ExceptionHandlers; Array.Sort(handlerInfoArray); //The order ensures that if interval[i] is nested in interval[j] then i < j GetOrderedCFGNodes(); foreach (YieldExceptionHandlerInfo handlerInfo in handlerInfoArray) { GenerateTryFinallyHandler(handlerInfo); } }
public void BuildGuardedBlocks(BlockLogicalConstruct theBlock) { if (this.methodContext.get_YieldData() == null) { return; } this.theBlock = this.DetermineTheBlock(theBlock); V_0 = this.methodContext.get_YieldData().get_FieldsInfo(); this.stateFieldRef = V_0.get_StateHolderField(); stackVariable17 = this.methodContext.get_YieldData().get_ExceptionHandlers(); Array.Sort <YieldExceptionHandlerInfo>(stackVariable17); this.GetOrderedCFGNodes(); V_1 = stackVariable17; V_2 = 0; while (V_2 < (int)V_1.Length) { this.GenerateTryFinallyHandler(V_1[V_2]); V_2 = V_2 + 1; } return; }
private void InitializeTheBlock() { this.MapBlocks(); V_0 = this.logicalBuilderContext.get_CFGBlockToLogicalConstructMap().get_Item(this.logicalBuilderContext.get_CFG().get_Blocks()[0])[0]; V_1 = new HashSet <ILogicalConstruct>(); V_2 = this.logicalBuilderContext.get_CFGBlockToLogicalConstructMap().get_Values().GetEnumerator(); try { while (V_2.MoveNext()) { V_3 = V_2.get_Current(); V_1.UnionWith(V_3); } } finally { ((IDisposable)V_2).Dispose(); } this.theBlockLogicalConstruct = new BlockLogicalConstruct(V_0, V_1); return; }
private void ProcessGotoFlowConstructs(BlockLogicalConstruct theConstruct) { V_0 = new ILogicalConstruct[theConstruct.get_Children().get_Count()]; V_1 = 0; V_3 = theConstruct.get_Children().GetEnumerator(); try { while (V_3.MoveNext()) { V_4 = (ILogicalConstruct)V_3.get_Current(); stackVariable14 = V_1; V_1 = stackVariable14 + 1; V_0[stackVariable14] = V_4; } } finally { ((IDisposable)V_3).Dispose(); } Array.Sort <ISingleEntrySubGraph>(V_0); V_2 = new HashSet <ILogicalConstruct>(); V_6 = V_0; V_7 = 0; while (V_7 < (int)V_6.Length) { V_8 = V_6[V_7]; if (this.visitedConstructs.Add(V_8)) { if (this.visitedConstructs.Contains(V_8.get_FollowNode()) || !V_2.Add(V_8.get_FollowNode())) { V_8.set_CFGFollowNode(null); } this.ProcessLogicalConstruct(V_8); } V_7 = V_7 + 1; } return; }
private void ProcessGotoFlowConstructs(BlockLogicalConstruct theConstruct) { ILogicalConstruct[] sortedChildren = new ILogicalConstruct[theConstruct.Children.Count]; int index = 0; foreach (ILogicalConstruct child in theConstruct.Children) { sortedChildren[index++] = child; } Array.Sort<ISingleEntrySubGraph>(sortedChildren); HashSet<ILogicalConstruct> usedAsFollow = new HashSet<ILogicalConstruct>(); foreach (ILogicalConstruct currentChild in sortedChildren) { if(visitedConstructs.Add(currentChild)) { if (visitedConstructs.Contains(currentChild.FollowNode) || !usedAsFollow.Add(currentChild.FollowNode)) { currentChild.CFGFollowNode = null; } ProcessLogicalConstruct(currentChild); } } }
/// <summary> /// Generates the try/finally construct that is represented by the specifed exception handler info and attaches it to the logical tree. /// </summary> /// <param name="handlerInfo"></param> private void GenerateTryFinallyHandler(YieldExceptionHandlerInfo handlerInfo) { finallyBlocks = new HashSet<ILogicalConstruct>(); entryOfTry = GetStateBeginBlockConstruct(handlerInfo.TryBeginState); BuildTryBody(handlerInfo); BlockLogicalConstruct newFinally; if (handlerInfo.HandlerType == YieldExceptionHandlerType.Method) { if (newFinallyBody == null) { throw new Exception("Could not determine the end ot the try block"); } RemoveExcessNodesFromTheTryBlock(); ProcessFinallyNodes(); newFinally = new BlockLogicalConstruct(newFinallyBody, new ILogicalConstruct[] { newFinallyBody }); } else { newFinally = GenerateFinallyBlock(); } BlockLogicalConstruct newTry = new BlockLogicalConstruct(entryOfTry, newTryBody); TryFinallyLogicalConstruct newTryFinallyConstruct = new TryFinallyLogicalConstruct(newTry, newFinally); createdConstructsToIntervalMap[newTryFinallyConstruct] = handlerInfo; CleanUpOrderedNodes(newTryFinallyConstruct); }