コード例 #1
0
        /// <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);
        }
コード例 #2
0
        /// <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);
        }