Changeset 810 for trunk


Ignore:
Timestamp:
2011-04-27T09:19:24+02:00 (4 years ago)
Author:
moo
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.