Changeset 810 in svn for trunk


Ignore:
Timestamp:
2011-04-27T07:19:24Z (4 years ago)
Author:
Xuefer
Message:

Decompiler: if/elseif/else

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r809 r810  
    709709    }
    710710    // }}}
     711    function isIfCondition(&$EX, $range) // {{{
     712    {
     713        $opcodes = &$EX['opcodes'];
     714        $firstOp = &$opcodes[$range[0]];
     715        return $firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP
     716         && !empty($opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'])
     717         && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1;
     718    }
     719    // }}}
    711720    function removeJmpInfo(&$EX, $line) // {{{
    712721    {
     
    828837            $this->recognizeAndDecompileClosedBlocks($EX, $bodyRange, $indent . INDENT);
    829838            echo $indent, '}', PHP_EOL;
     839            $this->endComplexBlock($EX);
     840            return;
     841        }
     842        // }}}
     843        // {{{ if/elseif/else
     844        if ($this->isIfCondition($EX, $range)) {
     845            $this->beginComplexBlock($EX);
     846            $isElseIf = false;
     847            do {
     848                $ifRange = array($range[0], $opcodes[$range[0]]['jmpouts'][0] - 1);
     849                $this->removeJmpInfo($EX, $ifRange[0]);
     850                $this->removeJmpInfo($EX, $ifRange[1]);
     851                $condition = $this->getOpVal($opcodes[$ifRange[0]]['op1'], $EX);
     852
     853                echo $indent, $isElseIf ? 'else if' : 'if', ' (', str($condition, $EX), ') ', '{', PHP_EOL;
     854                $this->recognizeAndDecompileClosedBlocks($EX, $ifRange, $indent . INDENT);
     855                $EX['lastBlock'] = null;
     856                echo $indent, '}', PHP_EOL;
     857
     858                $isElseIf = true;
     859                // search for else if
     860                $range[0] = $ifRange[1] + 1;
     861                for ($i = $ifRange[1] + 1; $i <= $range[1]; ++$i) {
     862                    // find first jmpout
     863                    if (!empty($opcodes[$i]['jmpouts'])) {
     864                        if ($this->isIfCondition($EX, array($i, $range[1]))) {
     865                            $this->dasmBasicBlock($EX, array($range[0], $i));
     866                            $range[0] = $i;
     867                        }
     868                        break;
     869                    }
     870                }
     871            } while ($this->isIfCondition($EX, $range));
     872            if ($ifRange[1] < $range[1]) {
     873                $elseRange = array($ifRange[1], $range[1]);
     874                echo $indent, 'else ', '{', PHP_EOL;
     875                $this->recognizeAndDecompileClosedBlocks($EX, $elseRange, $indent . INDENT);
     876                $EX['lastBlock'] = null;
     877                echo $indent, '}', PHP_EOL;
     878            }
    830879            $this->endComplexBlock($EX);
    831880            return;
Note: See TracChangeset for help on using the changeset viewer.