/// <summary> /// Processes a single statement from the decompiler and returns an AST entry for it /// </summary> /// <param name="network">The top-level network.</param> /// <param name="proc">The process where the method is located.</param> /// <param name="method">The method where the statement is found.</param> /// <param name="statement">The decompiler statement to process.</param> protected virtual BlockStatement Decompile(NetworkState network, ProcessState proc, MethodState method, ICSharpCode.Decompiler.CSharp.Syntax.BlockStatement statement) { var s = new BlockStatement { Parent = method }; method.StartScope(s); s.Statements = statement.Statements.Select(x => { var n = Decompile(network, proc, method, x); n.Parent = s; return(n); }).ToArray(); method.FinishScope(s); return(s); }
/// <summary> /// Processes a single statement from the decompiler and returns an AST entry for it /// </summary> /// <param name="network">The top-level network.</param> /// <param name="proc">The process where the method is located.</param> /// <param name="method">The method where the statement is found.</param> /// <param name="statement">The decompiler statement to process.</param> /*protected virtual ForStatement DecompileOld(NetworkState network, ProcessState proc, MethodState method, ICSharpCode.Decompiler.CSharp.Syntax.ForStatement statement) * { * if (statement.Initializers.Count != 1) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * if (statement.Iterators.Count != 1) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * * var init = statement.Initializers.First() as ICSharpCode.Decompiler.CSharp.Syntax.VariableDeclarationStatement; * if (init == null) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * if (init.Variables.Count != 1) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * var name = init.Variables.First().Name; * var initial = init.Variables.First().Initializer as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression; * * if (initial == null || !(initial.Value is int)) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * var startvalue = new Constant() * { * Source = initial, * DefaultValue = (int)initial.Value, * CecilType = LoadType(typeof(int)) * }; * * var cond = statement.Condition as ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression; * if (cond == null) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * if (cond.Operator != BinaryOperatorType.LessThan) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * var condleft = cond.Left as ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression; * var condright = cond.Right as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression; * * // Handling cases where the upper limit is the length of an array * if (condright == null) * { * // Some plus/minus expression * if (cond.Right is ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression) * { * var binop = cond.Right as ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression; * * var leftval = ResolveArrayLengthOrPrimitive(network, proc, method, binop.Left); * var rightval = ResolveArrayLengthOrPrimitive(network, proc, method, binop.Right); * * if (binop.Operator == BinaryOperatorType.Add) * condright = new ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression((int)leftval.DefaultValue + (int)rightval.DefaultValue); * else if (binop.Operator == BinaryOperatorType.Subtract) * condright = new ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression((int)leftval.DefaultValue - (int)rightval.DefaultValue); * else * throw new Exception(string.Format("Only add and subtract operations are supported in for loop bounds: {0}", statement)); * } * // Plain limit * else if (cond.Right is ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression || cond.Right is ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression) * { * condright = new ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression(ResolveArrayLengthOrPrimitive(network, proc, method, cond.Right)); * } * } * * if (condleft == null || condright == null || !(condright.Value is int) || condleft.Identifier != name) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * * var endvalue = new Constant() * { * Source = condright, * DefaultValue = (int)condright.Value, * CecilType = LoadType(typeof(int)) * }; * * var increment = new Constant() * { * DefaultValue = 1, * CecilType = LoadType(typeof(int)), * Source = cond * }; * * var itr = statement.Iterators.First() as ICSharpCode.Decompiler.CSharp.Syntax.ExpressionStatement; * if (itr == null || !(itr.Expression is ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression)) * { * var ae = itr == null ? null : itr.Expression as ICSharpCode.Decompiler.CSharp.Syntax.AssignmentExpression; * * if (ae != null && ae.Left is ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression && (ae.Left as ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression).Identifier == name && ae.Right is ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression) * { * // Support for increments like "i += 2" * increment = new Constant() * { * Source = ae.Right, * DefaultValue = ResolveArrayLengthOrPrimitive(network, proc, method, ae.Right as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression), * CecilType = LoadType(typeof(int)) * }; * } * else * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * } * else * { * var itre = itr.Expression as ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression; * var itro = itre.Expression as ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression; * * if (itro == null || itre.Operator != UnaryOperatorType.PostIncrement || itro.Identifier != name) * throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); * } * * var loopvar = new Variable() * { * CecilType = LoadType(typeof(int)), * Name = name, * Source = statement.Clone(), * DefaultValue = startvalue.DefaultValue * }; * * var res = new ForStatement() * { * StartValue = startvalue, * EndValue = endvalue, * Increment = increment, * LoopIndex = loopvar, * //LoopBody = Decompile(network, proc, method, statement.EmbeddedStatement), * Parent = method * }; * * method.StartScope(res); * method.AddVariable(loopvar); * * loopvar.Parent = res; * res.LoopBody = Decompile(network, proc, method, statement.EmbeddedStatement); * * res.LoopBody.Parent = res; * method.FinishScope(res); * * return res; * }*/ /// <summary> /// Processes a single statement from the decompiler and returns an AST entry for it /// </summary> /// <param name="network">The top-level network.</param> /// <param name="proc">The process where the method is located.</param> /// <param name="method">The method where the statement is found.</param> /// <param name="statement">The decompiler statement to process.</param> protected virtual ForStatement Decompile(NetworkState network, ProcessState proc, MethodState method, ICSharpCode.Decompiler.CSharp.Syntax.ForStatement statement) { if (statement.Initializers.Count != 1) { throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); } if (statement.Iterators.Count != 1) { throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); } var init = statement.Initializers.First() as ICSharpCode.Decompiler.CSharp.Syntax.VariableDeclarationStatement; if (init == null) { throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); } if (init.Variables.Count != 1) { throw new Exception(string.Format("Only plain style for loops supported: {0}", statement)); } var name = init.Variables.First().Name; var initial = init.Variables.First().Initializer; var itr = statement.Iterators.First() as ICSharpCode.Decompiler.CSharp.Syntax.ExpressionStatement; if (itr == null) { throw new Exception($"Unsupported iterator expression: {statement.Iterators.First()}"); } var loopvar = new Variable() { CecilType = LoadType(typeof(int)), Name = name, Source = statement.Clone(), }; if (initial is ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression) { loopvar.DefaultValue = (initial as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression).Value; } var res = new ForStatement() { LoopIndex = loopvar, Parent = method }; method.StartScope(res); method.AddVariable(loopvar); loopvar.Parent = res; res.Initializer = Decompile(network, proc, method, res, initial); res.Condition = Decompile(network, proc, method, res, statement.Condition); res.Increment = Decompile(network, proc, method, res, itr.Expression); res.LoopBody = Decompile(network, proc, method, statement.EmbeddedStatement); res.LoopBody.Parent = res; method.FinishScope(res); return(res); }