Ejemplo n.º 1
0
 public override void visit(DJumpCondition jcc)
 {
     if (jcc.getOperand(0).type == NodeType.Binary)
     {
         DBinary binary = (DBinary)jcc.getOperand(0);
         propagateInputs(binary.lhs, binary.rhs);
     }
 }
Ejemplo n.º 2
0
        private void writeDoWhileLoop(WhileLoop loop)
        {
            outputLine("do" + Environment.NewLine + "{");
            increaseIndent();
            if (loop.body != null)
            {
                writeBlock(loop.body);
            }

            string cond;

            if (loop.logic == null)
            {
                writeStatements(loop.source);
                decreaseIndent();

                DJumpCondition jcc = (DJumpCondition)loop.source.nodes.last;
                cond = buildExpression(jcc.getOperand(0));
            }
            else
            {
                decreaseIndent();
                cond = buildLogicChain(loop.logic);
            }

            outputLine("}");
            outputLine("while (" + cond + ");");
            if (loop.join != null)
            {
                writeBlock(loop.join);
            }
        }
Ejemplo n.º 3
0
        private void writeIf(IfBlock block)
        {
            string cond;

            if (block.logic == null)
            {
                writeStatements(block.source);

                DJumpCondition jcc = (DJumpCondition)block.source.nodes.last;

                if (block.invert)
                {
                    if (jcc.getOperand(0).type == NodeType.Unary &&
                        ((DUnary)jcc.getOperand(0)).spop == SPOpcode.not)
                    {
                        cond = buildExpression(jcc.getOperand(0).getOperand(0));
                    }
                    else if (jcc.getOperand(0).type == NodeType.Load)
                    {
                        cond = "!" + buildExpression(jcc.getOperand(0));
                    }
                    else
                    {
                        cond = "!(" + buildExpression(jcc.getOperand(0)) + ")";
                    }
                }
                else
                {
                    cond = buildExpression(jcc.getOperand(0));
                }
            }
            else
            {
                cond = buildLogicChain(block.logic);
                Debug.Assert(!block.invert);
            }

            outputLine("if (" + cond + ")");
            outputLine("{");
            increaseIndent();
            writeBlock(block.trueArm);
            decreaseIndent();
            if (block.falseArm != null &&
                BlockAnalysis.GetEmptyTarget(block.falseArm.source) == null)
            {
                outputLine("}");
                outputLine("else");
                outputLine("{");
                increaseIndent();
                writeBlock(block.falseArm);
                decreaseIndent();
            }
            outputLine("}");
            if (block.join != null)
            {
                writeBlock(block.join);
            }
        }
Ejemplo n.º 4
0
 public override void visit(DJumpCondition jcc)
 {
     if (jcc.getOperand(0).type == NodeType.Binary)
     {
         DBinary binary = (DBinary)jcc.getOperand(0);
         propagateInputs(binary.lhs, binary.rhs);
     }
 }
Ejemplo n.º 5
0
        private LogicChain buildLogicChain(NodeBlock block, NodeBlock earlyExitStop, out NodeBlock join)
        {
            DJumpCondition jcc   = (DJumpCondition)block.nodes.last;
            LogicChain     chain = new LogicChain(ToLogicOp(jcc));

            // Grab the true target, which will be either the "1" or "0"
            // branch of the AND/OR expression.
            NodeBlock earlyExit = BlockAnalysis.EffectiveTarget(jcc.trueTarget);

            NodeBlock exprBlock = block;

            do
            {
                do
                {
                    DJumpCondition childJcc = (DJumpCondition)exprBlock.nodes.last;
                    if (BlockAnalysis.EffectiveTarget(childJcc.trueTarget) != earlyExit)
                    {
                        // Parse a sub-expression.
                        NodeBlock  innerJoin;
                        LogicChain rhs = buildLogicChain(exprBlock, earlyExit, out innerJoin);
                        AssertInnerJoinValidity(innerJoin, earlyExit);
                        chain.append(rhs);
                        exprBlock = innerJoin;
                        childJcc  = (DJumpCondition)exprBlock.nodes.last;
                    }
                    else
                    {
                        chain.append(childJcc.getOperand(0));
                    }
                    exprBlock = childJcc.falseTarget;
                } while (exprBlock.nodes.last.type == NodeType.JumpCondition);

                do
                {
                    // We have reached the end of a sequence - a block containing
                    // a Constant and a Jump to the join point of the sequence.
                    //Debug.Assert(exprBlock.lir.instructions[0].op == Opcode.Constant);

                    // The next block is the join point.
                    NodeBlock      condBlock = SingleTarget(exprBlock);
                    var            last      = condBlock.nodes.last;
                    DJumpCondition condJcc;
                    try
                    {
                        condJcc = (DJumpCondition)last;
                    }
                    catch (Exception e)
                    {
                        throw new LogicChainConversionException(e.Message);
                    }

                    join = condBlock;

                    // If the cond block is the tagret of the early stop, we've
                    // gone a tad too far. This is the case for a simple
                    // expression like (a && b) || c.
                    if (earlyExitStop != null && SingleTarget(earlyExitStop) == condBlock)
                    {
                        return(chain);
                    }

                    // If the true connects back to the early exit stop, we're
                    // done.
                    if (BlockAnalysis.EffectiveTarget(condJcc.trueTarget) == earlyExitStop)
                    {
                        return(chain);
                    }

                    // If the true target does not have a shared target, we're
                    // done parsing the whole logic chain.
                    if (!HasSharedTarget(condBlock, condJcc))
                    {
                        return(chain);
                    }

                    // Otherwise, there is another link in the chain. This link
                    // joins the existing chain to a new subexpression, which
                    // actually starts hanging off the false branch of this
                    // conditional.
                    earlyExit = BlockAnalysis.EffectiveTarget(condJcc.trueTarget);

                    // Build the right-hand side of the expression.
                    NodeBlock  innerJoin;
                    LogicChain rhs = buildLogicChain(condJcc.falseTarget, earlyExit, out innerJoin);
                    AssertInnerJoinValidity(innerJoin, earlyExit);

                    // Build the full expression.
                    LogicChain root = new LogicChain(ToLogicOp(condJcc));
                    root.append(chain);
                    root.append(rhs);
                    chain = root;

                    // If the inner join's false target is a conditional, the
                    // outer expression may continue.
                    DJumpCondition innerJcc = (DJumpCondition)innerJoin.nodes.last;
                    if (innerJcc.falseTarget.nodes.last.type == NodeType.JumpCondition)
                    {
                        exprBlock = innerJcc.falseTarget;
                        break;
                    }

                    // Finally, the new expression block is always the early exit
                    // block. It's on the "trueTarget" edge of the expression,
                    // whereas incoming into this loop it's on the "falseTarget"
                    // edge, but this does not matter.
                    exprBlock = earlyExit;
                } while (true);
            } while (true);
        }