Exemple #1
0
        void SimplifyActionBlocks()
        {
            int index = 0;

            while (index < _blocks.Count)
            {
                ActionBlock block = _blocks [index];
                switch (block.ActionType)
                {
                case ActionType.ConditionalBranch:
                    // if condition goto label
                    // return expression
                    // label: return true
                    //      |
                    //      V
                    // return (condition || expression)
                    //
                    // label: return false
                    //      |
                    //      V
                    // return (!condition || expression)
                    ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)block;
                    if (IsReturnTrueOrFalse(cbr.Then) &&
                        IsReturn(cbr.Else) &&
                        1 == cbr.Then.Predecessors.Count &&
                        1 == cbr.Else.Predecessors.Count)
                    {
                        BinaryOperator op  = BinaryOperator.LogicalOr;
                        Expression     lhs = cbr.Condition;
                        Expression     rhs = ((ReturnActionBlock)cbr.Else).Expression;

                        if (((LiteralExpression)((ReturnActionBlock)cbr.Then).Expression).Value.Equals(0))
                        {
                            op = BinaryOperator.LogicalAnd;
                            _expressionDecompiler.Negate(lhs);
                            lhs = _expressionDecompiler.Pop();
                        }

                        ActionBlock newBlock = new ReturnActionBlock(
                            block.SourceInstruction,
                            new BinaryExpression(op, lhs, rhs));

                        _graph.ReplaceAt(index, newBlock);

                        index = 0;
                        continue;
                    }
                    break;
                }
                ++index;
            }
        }
		private ActionBlock OnReturn(ReturnActionBlock block)
		{
			Expression expression = block.Expression;
			VariableReferenceExpression variable = expression as VariableReferenceExpression;

			_queryExpression =
				variable != null
					? _variables[GetVariableIndex(variable)]
					: expression;

			return null;
		}
			void WriteReturn (ReturnActionBlock block)
			{
				_writer.Write ("return");
				if (null != block.Expression) {
					_writer.Write (" ");
					WriteExpression (block.Expression);
				}
			}
Exemple #4
0
        static bool IsReturnTrueOrFalse(ActionBlock block)
        {
            ReturnActionBlock ret = block as ReturnActionBlock;

            return(ret != null && IsTrueOrFalse(ret.Expression));
        }
		void SimplifyActionBlocks ()
		{
			int index = 0;
			while (index < _blocks.Count) {
				ActionBlock block = _blocks [index];
				switch (block.ActionType) {
				case ActionType.ConditionalBranch:
					/// if condition goto label
					/// return expression
					/// label: return true
					/// 		|
					/// 		V
					/// return (condition || expression)
					///
					/// label: return false
					/// 		|
					/// 		V
					/// return (!condition || expression)
					ConditionalBranchActionBlock cbr = (ConditionalBranchActionBlock)block;
					if (IsReturnTrueOrFalse (cbr.Then)
						&& IsReturn (cbr.Else)
						&& 1 == cbr.Then.Predecessors.Count
						&& 1 == cbr.Else.Predecessors.Count) {
						BinaryOperator op = BinaryOperator.LogicalOr;
						Expression lhs = cbr.Condition;
						Expression rhs = ((ReturnActionBlock) cbr.Else).Expression;

						if (((LiteralExpression) ((ReturnActionBlock) cbr.Then).Expression).Value.Equals (0)) {
							op = BinaryOperator.LogicalAnd;
							_expressionDecompiler.Negate (lhs);
							lhs = _expressionDecompiler.Pop ();
						}

						ActionBlock newBlock = new ReturnActionBlock (
							block.SourceInstruction,
							new BinaryExpression (op, lhs, rhs));

						_graph.ReplaceAt (index, newBlock);

						index = 0;
						continue;
					}
					break;
				}
				++index;
			}
		}