Changeset 795 for trunk/Decompiler.class.php
- Timestamp:
- 2011-04-26T07:28:21+02:00 (2 years ago)
- File:
-
- 1 edited
-
trunk/Decompiler.class.php (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Decompiler.class.php
r791 r795 615 615 function &fixOpcode($opcodes, $removeTailing = false, $defaultReturnValue = null) // {{{ 616 616 { 617 for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) { 617 $last = count($opcodes) - 1; 618 for ($i = 0; $i <= $last; $i ++) { 618 619 if (function_exists('xcache_get_fixed_opcode')) { 619 620 $opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i); … … 706 707 $lastOp = &$opcodes[$last]; 707 708 709 // {{{ try/catch 710 if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) { 711 $catchBlocks = array(); 712 $catchFirst = $firstOp['jmpins'][0]; 713 714 $tryFirst = $first; 715 $tryLast = $catchFirst - 1; 716 717 // search for XC_CATCH 718 $this->removeJmpInfo($EX, $catchFirst); 719 for ($i = $catchFirst; $i <= $last; ) { 720 if ($opcodes[$i]['opcode'] == XC_CATCH) { 721 $catchOpLine = $i; 722 $this->removeJmpInfo($EX, $catchOpLine); 723 724 $catchNext = $opcodes[$catchOpLine]['extended_value']; 725 $catchBodyLast = $catchNext - 1; 726 if ($opcodes[$catchBodyLast]['opcode'] == XC_JMP) { 727 --$catchBodyLast; 728 } 729 730 $catchBlocks[$catchFirst] = array($catchOpLine, $catchBodyLast); 731 732 $i = $catchFirst = $catchNext; 733 } 734 else { 735 ++$i; 736 } 737 } 738 739 if ($opcodes[$tryLast]['opcode'] == XC_JMP) { 740 --$tryLast; 741 } 742 743 $this->beginComplexBlock($EX); 744 echo $indent, 'try {', PHP_EOL; 745 $this->recognizeAndDecompileClosedBlocks($EX, $tryFirst, $tryLast, $indent . INDENT); 746 echo $indent, '}', PHP_EOL; 747 foreach ($catchBlocks as $catchFirst => $catchInfo) { 748 list($catchOpLine, $catchBodyLast) = $catchInfo; 749 $catchBodyFirst = $catchOpLine + 1; 750 $this->recognizeAndDecompileClosedBlocks($EX, $catchFirst, $catchOpLine, $indent); 751 $catchOp = &$opcodes[$catchOpLine]; 752 echo $indent, 'catch (', str($this->getOpVal($catchOp['op1'], $EX)), ' ', str($this->getOpVal($catchOp['op2'], $EX)), ') {', PHP_EOL; 753 unset($catchOp); 754 755 $EX['lastBlock'] = null; 756 $this->recognizeAndDecompileClosedBlocks($EX, $catchBodyFirst, $catchBodyLast, $indent . INDENT); 757 echo $indent, '}', PHP_EOL; 758 } 759 $this->endComplexBlock($EX); 760 return; 761 } 762 // }}} 763 708 764 if ($firstOp['opcode'] == XC_SWITCH_FREE && isset($T[$firstOp['op1']['var']])) { 709 765 // TODO: merge this code to CASE code. use SWITCH_FREE to detect begin of switch by using $Ts if possible … … 722 778 ) { 723 779 $cases = array(); 724 $caseNext = null;725 780 $caseDefault = null; 726 781 $caseOp = null; 727 for ($i = $first; $i <= $last; ++$i) {782 for ($i = $first; $i <= $last; ) { 728 783 $op = $opcodes[$i]; 729 784 if ($op['opcode'] == XC_CASE) { … … 734 789 assert('$jmpz["opcode"] == XC_JMPZ'); 735 790 $caseNext = $jmpz['jmpouts'][0]; 736 $i = $cases[$i] = $caseNext - 1; 737 } 738 else if ($op['opcode'] == XC_JMP) { 791 $cases[$i] = $caseNext - 1; 792 $i = $caseNext; 793 } 794 else if ($op['opcode'] == XC_JMP && $op['jmpouts'][0] >= $i) { 739 795 // default 740 if ($op['jmpouts'][0] >= $i) { 741 $caseNext = $op['jmpouts'][0]; 742 $caseDefault = $i; 743 $i = $cases[$i] = $caseNext - 1; 744 } 796 $caseNext = $op['jmpouts'][0]; 797 $caseDefault = $i; 798 $cases[$i] = $caseNext - 1; 799 $i = $caseNext; 800 } 801 else { 802 ++$i; 745 803 } 746 804 } … … 881 939 882 940 $starti = $first; 883 for ($i = $starti; $i <= $last; ++$i) { 884 $op = $opcodes[$i]; 885 if (!empty($op['jmpins']) || !empty($op['jmpouts'])) { 941 for ($i = $starti; $i <= $last; ) { 942 if (!empty($opcodes[$i]['jmpins']) || !empty($opcodes[$i]['jmpouts'])) { 886 943 $blockFirst = $i; 887 944 $blockLast = -1; … … 902 959 ++$j; 903 960 } while ($j <= $blockLast); 904 assert('$blockLast <= $last'); 961 if (!assert('$blockLast <= $last')) { 962 var_dump($blockLast, $last); 963 } 905 964 906 965 if ($blockLast >= $blockFirst) { … … 910 969 $this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent); 911 970 $starti = $blockLast + 1; 912 $i = $starti - 1; 913 continue; 914 } 971 $i = $starti; 972 } 973 else { 974 ++$i; 975 } 976 } 977 else { 978 ++$i; 915 979 } 916 980 } … … 924 988 $op_array['opcodes'] = $this->fixOpcode($op_array['opcodes'], true, $indent == '' ? 1 : null); 925 989 $opcodes = &$op_array['opcodes']; 990 $last = count($opcodes) - 1; 926 991 // {{{ build jmpins/jmpouts to op_array 927 for ($i = 0 , $cnt = count($opcodes); $i < $cnt; $i ++) {992 for ($i = 0; $i <= $last; $i ++) { 928 993 $op = &$opcodes[$i]; 929 994 $op['line'] = $i; … … 987 1052 $opcodes[$i + 2]['jmpins'][] = $i; 988 1053 break; 1054 1055 case XC_CATCH: 1056 $catchNext = $op['extended_value']; 1057 $op['jmpouts'] = array($catchNext); 1058 $opcodes[$catchNext]['jmpins'][] = $i; 1059 break; 989 1060 } 990 1061 /* … … 995 1066 } 996 1067 unset($op); 1068 if ($op_array['try_catch_array']) { 1069 foreach ($op_array['try_catch_array'] as $try_catch_element) { 1070 $catch_op = $try_catch_element['catch_op']; 1071 $try_op = $try_catch_element['try_op']; 1072 $opcodes[$try_op]['jmpins'][] = $catch_op; 1073 $opcodes[$catch_op]['jmpouts'][] = $try_op; 1074 $opcodes[$catch_op]['isCatchBegin'] = true; 1075 } 1076 } 997 1077 // }}} 998 1078 // build semi-basic blocks 999 1079 $nextbbs = array(); 1000 1080 $starti = 0; 1001 for ($i = 1 , $cnt = count($opcodes); $i < $cnt; $i ++) {1081 for ($i = 1; $i <= $last; $i ++) { 1002 1082 if (isset($opcodes[$i]['jmpins']) 1003 1083 || isset($opcodes[$i - 1]['jmpouts'])) { … … 1006 1086 } 1007 1087 } 1008 $nextbbs[$starti] = $ cnt;1088 $nextbbs[$starti] = $last + 1; 1009 1089 1010 1090 $EX = array(); … … 1239 1319 // }}} 1240 1320 case XC_CATCH: // {{{ 1241 $resvar = 'catch (' . str($this->getOpVal($op1, $EX)) . ' ' . str($this->getOpVal($op2, $EX)) . ')';1242 1321 break; 1243 1322 // }}} … … 2022 2101 function dumpop($op, &$EX) // {{{ 2023 2102 { 2103 assert('isset($op)'); 2024 2104 $op1 = $op['op1']; 2025 2105 $op2 = $op['op2']; … … 2053 2133 if ($k == 'result') { 2054 2134 var_dump($op); 2135 assert(0); 2055 2136 exit; 2056 assert(0);2057 2137 } 2058 2138 else { … … 2062 2142 } 2063 2143 $d[';'] = $op['extended_value']; 2144 if (!empty($op['jmpouts'])) { 2145 $d['>>'] = implode(',', $op['jmpouts']); 2146 } 2147 if (!empty($op['jmpins'])) { 2148 $d['<<'] = implode(',', $op['jmpins']); 2149 } 2064 2150 2065 2151 foreach ($d as $k => $v) {
Note: See TracChangeset
for help on using the changeset viewer.

