Changeset 790 for trunk/Decompiler.class.php
- Timestamp:
- 2011-04-25T16:36:10+02:00 (2 years ago)
- File:
-
- 1 edited
-
trunk/Decompiler.class.php (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Decompiler.class.php
r789 r790 564 564 } 565 565 echo $indent, str($op['php'], $indent), ";\n"; 566 $EX['lastBlock'] = 'basic'; 566 567 } 567 568 } … … 667 668 { 668 669 $this->dasmBasicBlock($EX, $first, $last); 669 // $this->dumpRange($EX, $first, $last );670 // $this->dumpRange($EX, $first, $last, $indent); 670 671 $this->outputPhp($EX, $first, $last, $indent); 671 672 } … … 699 700 function decompileComplexBlock(&$EX, $first, $last, $indent) // {{{ 700 701 { 702 $T = &$EX['Ts']; 701 703 $opcodes = &$EX['opcodes']; 702 704 703 705 $firstOp = &$opcodes[$first]; 704 706 $lastOp = &$opcodes[$last]; 707 708 if ($firstOp['opcode'] == XC_SWITCH_FREE && isset($T[$firstOp['op1']['var']])) { 709 // TODO: merge this code to CASE code. use SWITCH_FREE to detect begin of switch by using $Ts if possible 710 $this->beginComplexBlock($EX); 711 echo $indent, 'switch (' . str($this->getOpVal($firstOp['op1'], $EX)) . ') {', PHP_EOL; 712 echo $indent, '}', PHP_EOL; 713 $this->endComplexBlock($EX); 714 return; 715 } 716 717 if ( 718 ($firstOp['opcode'] == XC_CASE 719 || $firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0]]['opcode'] == XC_CASE 720 ) 721 && !empty($lastOp['jmpouts']) 722 ) { 723 $cases = array(); 724 $caseNext = null; 725 $caseDefault = null; 726 $caseOp = null; 727 for ($i = $first; $i <= $last; ++$i) { 728 $op = $opcodes[$i]; 729 if ($op['opcode'] == XC_CASE) { 730 if (!isset($caseOp)) { 731 $caseOp = $op; 732 } 733 $jmpz = $opcodes[$i + 1]; 734 assert('$jmpz["opcode"] == XC_JMPZ'); 735 $caseNext = $jmpz['jmpouts'][0]; 736 $i = $cases[$i] = $caseNext - 1; 737 } 738 else if ($op['opcode'] == XC_JMP) { 739 // default 740 if ($op['jmpouts'][0] >= $i) { 741 $caseNext = $op['jmpouts'][0]; 742 $caseDefault = $i; 743 $i = $cases[$i] = $caseNext - 1; 744 } 745 } 746 } 747 748 $this->beginComplexBlock($EX); 749 750 echo $indent, 'switch (', str($this->getOpVal($caseOp['op1'], $EX, true, true), $EX), ') {', PHP_EOL; 751 $caseIsOut = false; 752 foreach ($cases as $caseFirst => $caseLast) { 753 if ($caseIsOut && !empty($EX['lastBlock']) && empty($lastCaseFall)) { 754 echo PHP_EOL; 755 } 756 unset($EX['lastBlock']); 757 758 $caseOp = $opcodes[$caseFirst]; 759 760 echo $indent; 761 if ($caseOp['opcode'] == XC_CASE) { 762 echo 'case '; 763 echo str($this->getOpVal($caseOp['op2'], $EX), $EX); 764 echo ':', PHP_EOL; 765 766 $this->removeJmpInfo($EX, $caseFirst); 767 ++$caseFirst; 768 769 assert('$opcodes[$caseFirst]["opcode"] == XC_JMPZ'); 770 $this->removeJmpInfo($EX, $caseFirst); 771 ++$caseFirst; 772 } 773 else { 774 echo 'default'; 775 echo ':', PHP_EOL; 776 777 assert('$opcodes[$caseFirst]["opcode"] == XC_JMP'); 778 $this->removeJmpInfo($EX, $caseFirst); 779 ++$caseFirst; 780 } 781 782 assert('$opcodes[$caseLast]["opcode"] == XC_JMP'); 783 $this->removeJmpInfo($EX, $caseLast); 784 --$caseLast; 785 switch ($opcodes[$caseLast]['opcode']) { 786 case XC_BRK: 787 case XC_CONT: 788 case XC_GOTO: 789 $lastCaseFall = false; 790 break; 791 792 default: 793 $lastCaseFall = true; 794 } 795 796 $this->recognizeAndDecompileClosedBlocks($EX, $caseFirst, $caseLast, $indent . INDENT); 797 $caseIsOut = true; 798 } 799 echo $indent, '}', PHP_EOL; 800 801 $this->endComplexBlock($EX); 802 return; 803 } 705 804 706 805 if ($lastOp['opcode'] == XC_JMPNZ && !empty($lastOp['jmpouts']) … … 788 887 $blockLast = -1; 789 888 $i = $blockFirst; 889 // $this->dumpRange($EX, $i, $last, $indent); 790 890 do { 891 $op = $opcodes[$i]; 791 892 if (!empty($op['jmpins'])) { 792 893 // care about jumping from blocks behind, not before … … 810 911 $this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent); 811 912 $i = $starti = $blockLast + 1; 812 }813 continue;913 continue; 914 } 814 915 } 815 916 ++$i; … … 876 977 break; 877 978 */ 979 980 case XC_SWITCH_FREE: 981 $op['jmpouts'] = array($i + 1); 982 $opcodes[$i + 1]['jmpins'][] = $i; 983 break; 984 985 case XC_CASE: 986 // just to link together 987 $op['jmpouts'] = array($i + 2); 988 $opcodes[$i + 2]['jmpins'][] = $i; 989 break; 878 990 } 879 991 /* … … 914 1026 $EX['uses'] = array(); 915 1027 1028 $first = 0; 1029 $last = count($opcodes) - 1; 1030 1031 /* dump whole array 1032 $this->dasmBasicBlock($EX, $first, $last); 1033 for ($i = $first; $i <= $last; ++$i) { 1034 echo $i, "\t", $this->dumpop($opcodes[$i], $EX); 1035 } 1036 // */ 916 1037 // decompile in a tree way 917 $this->recognizeAndDecompileClosedBlocks($EX, 0, count($opcodes) - 1, $EX['indent']);1038 $this->recognizeAndDecompileClosedBlocks($EX, $first, $last, $EX['indent']); 918 1039 return $EX; 919 1040 } … … 1673 1794 // }}} 1674 1795 case XC_SWITCH_FREE: // {{{ 1675 // unset($T[$op1['var']]);1676 1796 break; 1677 1797 // }}} … … 1750 1870 // }}} 1751 1871 case XC_CASE: 1752 $switchValue = $this->getOpVal($op1, $EX);1872 // $switchValue = $this->getOpVal($op1, $EX); 1753 1873 $caseValue = $this->getOpVal($op2, $EX); 1754 $resvar = str($switchValue) . ' == ' . str($caseValue);1874 $resvar = $caseValue; 1755 1875 break; 1756 1876 case XC_RECV_INIT: … … 1949 2069 } 1950 2070 // }}} 1951 function dumpRange(&$EX, $first, $last ) // {{{2071 function dumpRange(&$EX, $first, $last, $indent = '') // {{{ 1952 2072 { 1953 2073 for ($i = $first; $i <= $last; ++$i) { 1954 echo $i , "\t"; $this->dumpop($EX['opcodes'][$i], $EX);1955 } 1956 echo "==", PHP_EOL;2074 echo $indent, $i, "\t"; $this->dumpop($EX['opcodes'][$i], $EX); 2075 } 2076 echo $indent, "==", PHP_EOL; 1957 2077 } 1958 2078 // }}}
Note: See TracChangeset
for help on using the changeset viewer.

