/// <summary> /// Update the variables used in the given node (and all children) using the given mapping function. /// </summary> private static void ReplaceVariables(AstNode node, Func <AstVariable, AstVariable> variableMapping) { var expr = node as AstExpression; if (expr != null) { var v = expr.Operand as AstVariable; if (v != null) { expr.Operand = variableMapping(v); } expr.Arguments.ForEach(x => ReplaceVariables(x, variableMapping)); } else { var catchBlock = node as AstTryCatchBlock.CatchBlock; if ((catchBlock != null) && (catchBlock.ExceptionVariable != null)) { catchBlock.ExceptionVariable = variableMapping(catchBlock.ExceptionVariable); } foreach (var child in node.GetChildren()) { ReplaceVariables(child, variableMapping); } } }
void AnalyzeNode(AstNode node) { AstExpression expr = node as AstExpression; if (expr != null) { AstVariable locVar = expr.Operand as AstVariable; if (locVar != null) { if (expr.Code == AstCode.Stloc) { numStloc[locVar] = numStloc.GetOrDefault(locVar) + 1; } else if (expr.Code == AstCode.Ldloc) { numLdloc[locVar] = numLdloc.GetOrDefault(locVar) + 1; } else if (expr.Code == AstCode.Ldloca) { numLdloca[locVar] = numLdloca.GetOrDefault(locVar) + 1; } else { throw new NotSupportedException(expr.Code.ToString()); } } foreach (AstExpression child in expr.Arguments) AnalyzeNode(child); } else { var catchBlock = node as AstTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null) { numStloc[catchBlock.ExceptionVariable] = numStloc.GetOrDefault(catchBlock.ExceptionVariable) + 1; } foreach (AstNode child in node.GetChildren()) AnalyzeNode(child); } }
private void VisitChilden(AstNode node) { foreach (var child in node.GetChildren()) { child.Accept(this); } }
/// <summary> /// Creates the "ExpressionToInfer" instances (=nodes in dependency graph) /// </summary> /// <remarks> /// We are using a dependency graph to ensure that expressions are analyzed in the correct order. /// </remarks> private void CreateDependencyGraph(AstNode node) { var catchBlock = node as AstTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null && catchBlock.ExceptionType != null && catchBlock.ExceptionVariable.Type == null) { catchBlock.ExceptionVariable.Type = catchBlock.ExceptionType; } var expr = node as AstExpression; if (expr != null) { var expressionToInfer = new ExpressionToInfer(expr); allExpressions.Add(expressionToInfer); FindNestedAssignments(expr, expressionToInfer); if ((expr.Code == AstCode.Stloc) && ((AstVariable) expr.Operand).Type == null) { assignmentExpressions[(AstVariable)expr.Operand].Add(expressionToInfer); } return; } foreach (var child in node.GetChildren()) { CreateDependencyGraph(child); } }
/// <summary> /// Flattens all nested basic blocks, except the the top level 'node' argument /// </summary> private static void FlattenBasicBlocks(AstNode node) { var block = node as AstBlock; if (block != null) { var flatBody = new List <AstNode>(); foreach (var child in block.GetChildren()) { FlattenBasicBlocks(child); var childAsBB = child as AstBasicBlock; if (childAsBB != null) { if (!(childAsBB.Body.FirstOrDefault() is AstLabel)) { throw new Exception("Basic block has to start with a label. \n" + childAsBB); } if (childAsBB.Body.LastOrDefault() is AstExpression && !childAsBB.Body.LastOrDefault().IsUnconditionalControlFlow()) { // I got this error when using mapsforge, in createBitmap() // https://raw.githubusercontent.com/mapsforge/mapsforge/master/mapsforge-map/src/main/java/org/mapsforge/map/rendertheme/XmlUtils.java // Apparently it is related to the finally statement. // I have no idea what it means to disable this check. //throw new Exception("Basic block has to end with unconditional control flow. \n" + childAsBB); } flatBody.AddRange(childAsBB.GetChildren()); } else { flatBody.Add(child); } } block.EntryGoto = null; block.Body = flatBody; } else if (node is AstExpression) { // Optimization - no need to check expressions } else if (node != null) { // Recursively find all ILBlocks foreach (var child in node.GetChildren()) { FlattenBasicBlocks(child); } } }
void AnalyzeNode(AstNode node) { AstExpression expr = node as AstExpression; if (expr != null) { AstVariable locVar = expr.Operand as AstVariable; if (locVar != null) { if (expr.Code == AstCode.Stloc) { numStloc[locVar] = numStloc.GetOrDefault(locVar) + 1; } else if (expr.Code == AstCode.Ldloc) { numLdloc[locVar] = numLdloc.GetOrDefault(locVar) + 1; } else if (expr.Code == AstCode.Ldloca) { numLdloca[locVar] = numLdloca.GetOrDefault(locVar) + 1; } else { throw new NotSupportedException(expr.Code.ToString()); } } foreach (AstExpression child in expr.Arguments) { AnalyzeNode(child); } } else { var catchBlock = node as AstTryCatchBlock.CatchBlock; if (catchBlock != null && catchBlock.ExceptionVariable != null) { numStloc[catchBlock.ExceptionVariable] = numStloc.GetOrDefault(catchBlock.ExceptionVariable) + 1; } foreach (AstNode child in node.GetChildren()) { AnalyzeNode(child); } } }
/// <summary> /// Flattens all nested basic blocks, except the the top level 'node' argument /// </summary> private static void FlattenBasicBlocks(AstNode node) { var block = node as AstBlock; if (block != null) { var flatBody = new List <AstNode>(); foreach (var child in block.GetChildren()) { FlattenBasicBlocks(child); var childAsBB = child as AstBasicBlock; if (childAsBB != null) { if (!(childAsBB.Body.FirstOrDefault() is AstLabel)) { throw new Exception("Basic block has to start with a label. \n" + childAsBB); } if (childAsBB.Body.LastOrDefault() is AstExpression && !childAsBB.Body.LastOrDefault().IsUnconditionalControlFlow()) { throw new Exception("Basic block has to end with unconditional control flow. \n" + childAsBB); } flatBody.AddRange(childAsBB.GetChildren()); } else { flatBody.Add(child); } } block.EntryGoto = null; block.Body = flatBody; } else if (node is AstExpression) { // Optimization - no need to check expressions } else if (node != null) { // Recursively find all ILBlocks foreach (var child in node.GetChildren()) { FlattenBasicBlocks(child); } } }