Changeset 800


Ignore:
Timestamp:
2011-04-27T04:45:42+02:00 (4 years ago)
Author:
moo
Message:

Decompiler: use range to simplify calling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r799 r800  
    555555    } 
    556556    // }}} 
    557     function outputPhp(&$EX, $opline, $last, $indent) // {{{ 
     557    function outputPhp(&$EX, $range, $indent) // {{{ 
    558558    { 
    559559        $needBlankline = isset($EX['lastBlock']); 
    560560        $origindent = $indent; 
    561561        $curticks = 0; 
    562         for ($i = $opline; $i <= $last; $i ++) { 
     562        for ($i = $range[0]; $i <= $range[1]; $i ++) { 
    563563            $op = $EX['opcodes'][$i]; 
    564564            if (isset($op['gofrom'])) { 
     
    699699    } 
    700700    // }}} 
    701     function decompileBasicBlock(&$EX, $first, $last, $indent) // {{{ 
    702     { 
    703         $this->dasmBasicBlock($EX, $first, $last); 
    704         // $this->dumpRange($EX, $first, $last, $indent); 
    705         $this->outputPhp($EX, $first, $last, $indent); 
     701    function decompileBasicBlock(&$EX, $range, $indent) // {{{ 
     702    { 
     703        $this->dasmBasicBlock($EX, $range); 
     704        // $this->dumpRange($EX, $range, $indent); 
     705        $this->outputPhp($EX, $range, $indent); 
    706706    } 
    707707    // }}} 
     
    732732    } 
    733733    // }}} 
    734     function decompileComplexBlock(&$EX, $first, $last, $indent) // {{{ 
     734    function decompileComplexBlock(&$EX, $range, $indent) // {{{ 
    735735    { 
    736736        $T = &$EX['Ts']; 
    737737        $opcodes = &$EX['opcodes']; 
    738738 
    739         $firstOp = &$opcodes[$first]; 
    740         $lastOp = &$opcodes[$last]; 
     739        $firstOp = &$opcodes[$range[0]]; 
     740        $lastOp = &$opcodes[$range[1]]; 
    741741 
    742742        // {{{ ?: excludign JMP_SET 
    743743        if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) 
    744          && $last >= $first + 3 
     744         && $range[1] >= $range[0] + 3 
    745745         && $opcodes[$firstOp['jmpouts'][0] - 2]['opcode'] == XC_QM_ASSIGN 
    746          && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $last + 1 
     746         && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1 
    747747         && $lastOp['opcode'] == XC_QM_ASSIGN 
    748748        ) { 
    749             $trueFirst = $first + 1; 
    750             $trueLast = $firstOp['jmpouts'][0] - 2; 
    751             $falseFirst = $firstOp['jmpouts'][0]; 
    752             $falseLast = $last; 
    753             $this->removeJmpInfo($EX, $first); 
     749            $trueRange = array($range[0] + 1, $firstOp['jmpouts'][0] - 2); 
     750            $falseRange = array($firstOp['jmpouts'][0], $range[1]); 
     751            $this->removeJmpInfo($EX, $range[0]); 
    754752 
    755753            $condition = $this->getOpVal($firstOp['op1'], $EX); 
    756             $this->recognizeAndDecompileClosedBlocks($EX, $trueFirst, $trueLast, $indent . INDENT); 
    757             $trueValue = $this->getOpVal($opcodes[$trueLast]['op1'], $EX, false, true); 
    758             $this->recognizeAndDecompileClosedBlocks($EX, $falseFirst, $falseLast, $indent . INDENT); 
    759             $falseValue = $this->getOpVal($opcodes[$falseLast]['op1'], $EX, false, true); 
    760             $T[$opcodes[$trueLast]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue); 
     754            $this->recognizeAndDecompileClosedBlocks($EX, $trueRange, $indent . INDENT); 
     755            $trueValue = $this->getOpVal($opcodes[$trueRange[1]]['op1'], $EX, false, true); 
     756            $this->recognizeAndDecompileClosedBlocks($EX, $falseRange, $indent . INDENT); 
     757            $falseValue = $this->getOpVal($opcodes[$falseRange[1]]['op1'], $EX, false, true); 
     758            $T[$opcodes[$trueRange[1]]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue); 
    761759            return false; 
    762760        } 
     
    767765            $catchFirst = $firstOp['jmpins'][0]; 
    768766 
    769             $tryFirst = $first; 
    770             $tryLast = $catchFirst - 1; 
     767            $tryRange = array($range[0], $catchFirst - 1); 
    771768 
    772769            // search for XC_CATCH 
    773770            $this->removeJmpInfo($EX, $catchFirst); 
    774             for ($i = $catchFirst; $i <= $last; ) { 
     771            for ($i = $catchFirst; $i <= $range[1]; ) { 
    775772                if ($opcodes[$i]['opcode'] == XC_CATCH) { 
    776773                    $catchOpLine = $i; 
     
    792789            } 
    793790 
    794             if ($opcodes[$tryLast]['opcode'] == XC_JMP) { 
    795                 --$tryLast; 
     791            if ($opcodes[$tryRange[1]]['opcode'] == XC_JMP) { 
     792                --$tryRange[1]; 
    796793            } 
    797794 
    798795            $this->beginComplexBlock($EX); 
    799796            echo $indent, "try {", PHP_EOL; 
    800             $this->recognizeAndDecompileClosedBlocks($EX, $tryFirst, $tryLast, $indent . INDENT); 
     797            $this->recognizeAndDecompileClosedBlocks($EX, $tryRange, $indent . INDENT); 
    801798            echo $indent, '}', PHP_EOL; 
    802799            foreach ($catchBlocks as $catchFirst => $catchInfo) { 
    803800                list($catchOpLine, $catchBodyLast) = $catchInfo; 
    804801                $catchBodyFirst = $catchOpLine + 1; 
    805                 $this->recognizeAndDecompileClosedBlocks($EX, $catchFirst, $catchOpLine, $indent); 
     802                $this->recognizeAndDecompileClosedBlocks($EX, array($catchFirst, $catchOpLine), $indent); 
    806803                $catchOp = &$opcodes[$catchOpLine]; 
    807804                echo $indent, 'catch (', str($this->getOpVal($catchOp['op1'], $EX)), ' ', str($this->getOpVal($catchOp['op2'], $EX)), ") {", PHP_EOL; 
     
    809806 
    810807                $EX['lastBlock'] = null; 
    811                 $this->recognizeAndDecompileClosedBlocks($EX, $catchBodyFirst, $catchBodyLast, $indent . INDENT); 
     808                $this->recognizeAndDecompileClosedBlocks($EX, array($catchBodyFirst, $catchBodyLast), $indent . INDENT); 
    812809                echo $indent, '}', PHP_EOL; 
    813810            } 
     
    835832            $caseDefault = null; 
    836833            $caseOp = null; 
    837             for ($i = $first; $i <= $last; ) { 
     834            for ($i = $range[0]; $i <= $range[1]; ) { 
    838835                $op = $opcodes[$i]; 
    839836                if ($op['opcode'] == XC_CASE) { 
     
    907904                } 
    908905 
    909                 $this->recognizeAndDecompileClosedBlocks($EX, $caseFirst, $caseLast, $indent . INDENT); 
     906                $this->recognizeAndDecompileClosedBlocks($EX, array($caseFirst, $caseLast), $indent . INDENT); 
    910907                $caseIsOut = true; 
    911908            } 
     
    918915        // {{{ do/while 
    919916        if ($lastOp['opcode'] == XC_JMPNZ && !empty($lastOp['jmpouts']) 
    920          && $lastOp['jmpouts'][0] == $first) { 
    921             $this->removeJmpInfo($EX, $last); 
     917         && $lastOp['jmpouts'][0] == $range[0]) { 
     918            $this->removeJmpInfo($EX, $range[1]); 
    922919            $this->beginComplexBlock($EX); 
    923920 
    924921            echo $indent, "do {", PHP_EOL; 
    925             $this->recognizeAndDecompileClosedBlocks($EX, $first, $last, $indent . INDENT); 
     922            $this->recognizeAndDecompileClosedBlocks($EX, $range, $indent . INDENT); 
    926923            echo $indent, "} while (", str($this->getOpVal($lastOp['op1'], $EX)), ');', PHP_EOL; 
    927924 
     
    934931        $firstJmp = null; 
    935932        $firstJmpOp = null; 
    936         for ($i = $first; $i <= $last; ++$i) { 
     933        for ($i = $range[0]; $i <= $range[1]; ++$i) { 
    937934            if (!empty($opcodes[$i]['jmpouts'])) { 
    938935                $firstJmp = $i; 
     
    946943        if (isset($firstJmpOp) 
    947944         && $firstJmpOp['opcode'] == XC_JMPZ 
    948          && $firstJmpOp['jmpouts'][0] > $last 
     945         && $firstJmpOp['jmpouts'][0] > $range[1] 
    949946         && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) 
    950          && $lastOp['jmpouts'][0] == $first) { 
     947         && $lastOp['jmpouts'][0] == $range[0]) { 
    951948            $this->removeJmpInfo($EX, $firstJmp); 
    952             $this->removeJmpInfo($EX, $last); 
     949            $this->removeJmpInfo($EX, $range[1]); 
    953950            $this->beginComplexBlock($EX); 
    954951 
    955952            ob_start(); 
    956             $this->recognizeAndDecompileClosedBlocks($EX, $first, $last, $indent . INDENT); 
     953            $this->recognizeAndDecompileClosedBlocks($EX, $range, $indent . INDENT); 
    957954            $body = ob_get_clean(); 
    958955 
     
    968965        if (isset($firstJmpOp) 
    969966         && $firstJmpOp['opcode'] == XC_FE_FETCH 
    970          && $firstJmpOp['jmpouts'][0] > $last 
     967         && $firstJmpOp['jmpouts'][0] > $range[1] 
    971968         && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) 
    972969         && $lastOp['jmpouts'][0] == $firstJmp) { 
    973970            $this->removeJmpInfo($EX, $firstJmp); 
    974             $this->removeJmpInfo($EX, $last); 
     971            $this->removeJmpInfo($EX, $range[1]); 
    975972            $this->beginComplexBlock($EX); 
    976973 
    977974            ob_start(); 
    978             $this->recognizeAndDecompileClosedBlocks($EX, $first, $last, $indent . INDENT); 
     975            $this->recognizeAndDecompileClosedBlocks($EX, $range, $indent . INDENT); 
    979976            $body = ob_get_clean(); 
    980977 
     
    993990        // }}} 
    994991 
    995         $this->decompileBasicBlock($EX, $first, $last, $indent); 
     992        $this->decompileBasicBlock($EX, $range, $indent); 
    996993    } 
    997994    // }}} 
    998     function recognizeAndDecompileClosedBlocks(&$EX, $first, $last, $indent) // {{{ decompile in a tree way 
     995    function recognizeAndDecompileClosedBlocks(&$EX, $range, $indent) // {{{ decompile in a tree way 
    999996    { 
    1000997        $opcodes = &$EX['opcodes']; 
    1001998 
    1002         $starti = $first; 
    1003         for ($i = $starti; $i <= $last; ) { 
     999        $starti = $range[0]; 
     1000        for ($i = $starti; $i <= $range[1]; ) { 
    10041001            if (!empty($opcodes[$i]['jmpins']) || !empty($opcodes[$i]['jmpouts'])) { 
    10051002                $blockFirst = $i; 
     
    10111008                        // care about jumping from blocks behind, not before 
    10121009                        foreach ($op['jmpins'] as $oplineNumber) { 
    1013                             if ($oplineNumber <= $last && $blockLast < $oplineNumber) { 
     1010                            if ($oplineNumber <= $range[1] && $blockLast < $oplineNumber) { 
    10141011                                $blockLast = $oplineNumber; 
    10151012                            } 
     
    10211018                    ++$j; 
    10221019                } while ($j <= $blockLast); 
    1023                 if (!assert('$blockLast <= $last')) { 
    1024                     var_dump($blockLast, $last); 
     1020                if (!assert('$blockLast <= $range[1]')) { 
     1021                    var_dump($blockLast, $range[1]); 
    10251022                } 
    10261023 
    10271024                if ($blockLast >= $blockFirst) { 
    10281025                    if ($blockFirst > $starti) { 
    1029                         $this->decompileBasicBlock($EX, $starti, $blockFirst - 1, $indent); 
    1030                     } 
    1031                     if ($this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent) === false) { 
     1026                        $this->decompileBasicBlock($EX, array($starti, $blockFirst - 1), $indent); 
     1027                    } 
     1028                    if ($this->decompileComplexBlock($EX, array($blockFirst, $blockLast), $indent) === false) { 
    10321029                        if ($EX['lastBlock'] == 'complex') { 
    10331030                            echo PHP_EOL; 
     
    10461043            } 
    10471044        } 
    1048         if ($starti <= $last) { 
    1049             $this->decompileBasicBlock($EX, $starti, $last, $indent); 
     1045        if ($starti <= $range[1]) { 
     1046            $this->decompileBasicBlock($EX, array($starti, $range[1]), $indent); 
    10501047        } 
    10511048    } 
     
    11611158        $EX['op_array'] = &$op_array; 
    11621159        $EX['opcodes'] = &$opcodes; 
     1160        $EX['range'] = array(0, count($opcodes) - 1); 
    11631161        // func call 
    11641162        $EX['object'] = null; 
     
    11671165        $EX['argstack'] = array(); 
    11681166        $EX['arg_types_stack'] = array(); 
    1169         $EX['last'] = count($opcodes) - 1; 
    11701167        $EX['silence'] = 0; 
    11711168        $EX['recvs'] = array(); 
     
    11731170        $EX['lastBlock'] = null; 
    11741171 
    1175         $first = 0; 
    1176         $last = count($opcodes) - 1; 
    1177  
    11781172        /* dump whole array 
    11791173        $this->keepTs = true; 
    1180         $this->dasmBasicBlock($EX, $first, $last); 
    1181         for ($i = $first; $i <= $last; ++$i) { 
     1174        $this->dasmBasicBlock($EX, $range); 
     1175        for ($i = $range[0]; $i <= $range[1]; ++$i) { 
    11821176            echo $i, "\t", $this->dumpop($opcodes[$i], $EX); 
    11831177        } 
    11841178        // */ 
    11851179        // decompile in a tree way 
    1186         $this->recognizeAndDecompileClosedBlocks($EX, $first, $last, $EX['indent']); 
     1180        $this->recognizeAndDecompileClosedBlocks($EX, $EX['range'], $EX['indent']); 
    11871181        return $EX; 
    11881182    } 
    11891183    // }}} 
    1190     function outputCode(&$EX, $opline, $last, $indent, $loop = false) // {{{ 
    1191     { 
    1192         $op = &$EX['opcodes'][$opline]; 
    1193         $next = $EX['nextbbs'][$opline]; 
     1184    function outputCode(&$EX, $range, $indent, $loop = false) // {{{ 
     1185    { 
     1186        $op = &$EX['opcodes'][$range[0]]; 
     1187        $next = $EX['nextbbs'][$range[0]]; 
    11941188 
    11951189        $end = $next - 1; 
    1196         if ($end > $last) { 
    1197             $end = $last; 
     1190        if ($end > $range[1]) { 
     1191            $end = $range[1]; 
    11981192        } 
    11991193 
     
    12041198            // echo ";;;\n"; 
    12051199        } 
    1206         $this->dasmBasicBlock($EX, $opline, $end); 
    1207         $this->outputPhp($EX, $opline, $end, $indent); 
     1200        $this->dasmBasicBlock($EX, array($opline, $end)); 
     1201        $this->outputPhp($EX, array($opline, $end), $indent); 
    12081202        // jmpout op 
    12091203        $op = &$EX['opcodes'][$end]; 
     
    12141208 
    12151209        if (isset($EX['opcodes'][$next])) { 
    1216             if (isset($last) && $next > $last) { 
     1210            if (isset($range[1]) && $next > $range[1]) { 
    12171211                $next = null; 
    12181212            } 
     
    12321226                        $cond = $op['cond']; 
    12331227                        echo "{$indent}if ($cond) {\n"; 
    1234                         $this->outputCode($EX, $next, $last, INDENT . $indent); 
     1228                        $this->outputCode($EX, $next, $range[1], INDENT . $indent); 
    12351229                        echo "$indent}\n"; 
    1236                         $this->outputCode($EX, $target, $last, $indent); 
     1230                        $this->outputCode($EX, $target, $range[1], $indent); 
    12371231                        return; 
    12381232                    } 
     
    12841278                $EX['Ts'][$var] = '(' . $fromop['and_or'] . " $opstr " . $EX['Ts'][$var] . ')'; 
    12851279            } 
    1286             #$this->outputCode($EX, $next, $last, $indent); 
     1280            #$this->outputCode($EX, $next, $range[1], $indent); 
    12871281            #return; 
    12881282        } 
     
    12991293        } 
    13001294 
     1295        $nextRange = array($next, $range[1]); 
    13011296        if ($loop) { 
    1302             return array($next, $last); 
    1303         } 
    1304         $this->outputCode($EX, $next, $last, $indent); 
     1297            return $nextRange; 
     1298        } 
     1299        $this->outputCode($EX, $nextRange, $indent); 
    13051300    } 
    13061301    // }}} 
    1307     function dasmBasicBlock(&$EX, $opline, $last) // {{{ 
     1302    function dasmBasicBlock(&$EX, $range) // {{{ 
    13081303    { 
    13091304        $T = &$EX['Ts']; 
     
    13111306        $lastphpop = null; 
    13121307 
    1313         for ($i = $opline; $i <= $last; $i ++) { 
     1308        for ($i = $range[0]; $i <= $range[1]; $i ++) { 
    13141309            // {{{ prepair 
    13151310            $op = &$opcodes[$i]; 
     
    18021797 
    18031798                    for (;;) { 
    1804                         if ($i + 1 <= $last 
     1799                        if ($i + 1 <= $range[1] 
    18051800                         && $opcodes[$i + 1]['opcode'] == XC_ADD_INTERFACE 
    18061801                         && $opcodes[$i + 1]['op1']['var'] == $res['var']) { 
    18071802                            // continue 
    18081803                        } 
    1809                         else if ($i + 2 <= $last 
     1804                        else if ($i + 2 <= $range[1] 
    18101805                         && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE 
    18111806                         && $opcodes[$i + 2]['op1']['var'] == $res['var'] 
     
    22302225    } 
    22312226    // }}} 
    2232     function dumpRange(&$EX, $first, $last, $indent = '') // {{{ 
    2233     { 
    2234         for ($i = $first; $i <= $last; ++$i) { 
     2227    function dumpRange(&$EX, $range, $indent = '') // {{{ 
     2228    { 
     2229        for ($i = $range[0]; $i <= $range[1]; ++$i) { 
    22352230            echo $indent, $i, "\t"; $this->dumpop($EX['opcodes'][$i], $EX); 
    22362231        } 
Note: See TracChangeset for help on using the changeset viewer.