Ignore:
Timestamp:
2011-06-04T05:34:36+02:00 (4 years ago)
Author:
moo
Message:

merge from trunk: disassembler/decompiler improvements

Location:
branches/1.3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/1.3

  • branches/1.3/Decompiler.class.php

    r784 r817  
    150150    var $op2; 
    151151    var $parent; 
    152     var $indent; 
    153152 
    154153    function Decompiler_Binop($parent, $op1, $opc, $op2) 
     
    164163        $opstr = $this->parent->binops[$this->opc]; 
    165164 
    166         $op1 = foldToCode($this->op1, $indent); 
    167         if (is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) { 
    168             $op1 = "(" . str($op1, $indent) . ")"; 
    169         } 
    170         $op2 = foldToCode($this->op2, $indent); 
    171         if (is_a($this->op2, 'Decompiler_Binop') && $this->op2->opc != $this->opc && substr($opstr, -1) != '=') { 
    172             $op2 = "(" . str($op2, $indent) . ")"; 
     165        if (is_a($this->op1, 'Decompiler_TriOp') || is_a($this->op1, 'Decompiler_Binop') && $this->op1->opc != $this->opc) { 
     166            $op1 = "(" . str($this->op1, $indent) . ")"; 
     167        } 
     168        else { 
     169            $op1 = $this->op1; 
     170        } 
     171 
     172        if (is_a($this->op2, 'Decompiler_TriOp') || is_a($this->op2, 'Decompiler_Binop') && $this->op2->opc != $this->opc && substr($opstr, -1) != '=') { 
     173            $op2 = "(" . str($this->op2, $indent) . ")"; 
     174        } 
     175        else { 
     176            $op2 = $this->op2; 
    173177        } 
    174178 
     
    177181        } 
    178182 
    179         return str($op1) . ' ' . $opstr . ' ' . str($op2); 
     183        return str($op1, $indent) . ' ' . $opstr . ($this->opc == XC_ASSIGN_REF ? '' : ' ') . str($op2, $indent); 
     184    } 
     185} 
     186// }}} 
     187class Decompiler_TriOp extends Decompiler_Code // {{{ 
     188{ 
     189    var $condition; 
     190    var $trueValue; 
     191    var $falseValue; 
     192 
     193    function Decompiler_TriOp($condition, $trueValue, $falseValue) 
     194    { 
     195        $this->condition = $condition; 
     196        $this->trueValue = $trueValue; 
     197        $this->falseValue = $falseValue; 
     198    } 
     199 
     200    function toCode($indent) 
     201    { 
     202        $trueValue = $this->trueValue; 
     203        if (is_a($this->trueValue, 'Decompiler_TriOp')) { 
     204            $trueValue = "(" . str($trueValue, $indent) . ")"; 
     205        } 
     206        $falseValue = $this->falseValue; 
     207        if (is_a($this->falseValue, 'Decompiler_TriOp')) { 
     208            $falseValue = "(" . str($falseValue, $indent) . ")"; 
     209        } 
     210 
     211        return str($this->condition) . ' ? ' . str($trueValue) . ' : ' . str($falseValue); 
    180212    } 
    181213} 
     
    486518                XC_ASSIGN_BW_XOR       => "^=", 
    487519                XC_BOOL_XOR            => "xor", 
     520                XC_ASSIGN              => "=", 
     521                XC_ASSIGN_REF          => "= &", 
     522                XC_JMP_SET             => "?:", 
     523                XC_JMPZ_EX             => "&&", 
     524                XC_JMPNZ_EX            => "||", 
    488525                ); 
    489526        // }}} 
     
    522559    } 
    523560    // }}} 
    524     function outputPhp(&$opcodes, $opline, $last, $indent) // {{{ 
    525     { 
    526         $origindent = $indent; 
     561    function outputPhp(&$EX, $range) // {{{ 
     562    { 
     563        $needBlankline = isset($EX['lastBlock']); 
     564        $indent = $EX['indent']; 
    527565        $curticks = 0; 
    528         for ($i = $opline; $i <= $last; $i ++) { 
    529             $op = $opcodes[$i]; 
     566        for ($i = $range[0]; $i <= $range[1]; $i ++) { 
     567            $op = $EX['opcodes'][$i]; 
     568            if (isset($op['gofrom'])) { 
     569                if ($needBlankline) { 
     570                    $needBlankline = false; 
     571                    echo PHP_EOL; 
     572                } 
     573                echo 'label' . $i, ":\n"; 
     574            } 
    530575            if (isset($op['php'])) { 
    531576                $toticks = isset($op['ticks']) ? (int) str($op['ticks']) : 0; 
     
    534579                    $curticks = $toticks; 
    535580                    if (!$curticks) { 
    536                         echo $origindent, "}\n\n"; 
    537                         $indent = $origindent; 
     581                        echo $EX['indent'], "}\n\n"; 
     582                        $indent = $EX['indent']; 
    538583                    } 
    539584                    else { 
    540585                        if ($oldticks) { 
    541                             echo $origindent, "}\n\n"; 
     586                            echo $EX['indent'], "}\n\n"; 
    542587                        } 
    543588                        else if (!$oldticks) { 
    544589                            $indent .= INDENT; 
    545590                        } 
    546                         echo $origindent, "declare (ticks=$curticks) {\n"; 
    547                     } 
     591                        if ($needBlankline) { 
     592                            $needBlankline = false; 
     593                            echo PHP_EOL; 
     594                        } 
     595                        echo $EX['indent'], "declare (ticks=$curticks) {\n"; 
     596                    } 
     597                } 
     598                if ($needBlankline) { 
     599                    $needBlankline = false; 
     600                    echo PHP_EOL; 
    548601                } 
    549602                echo $indent, str($op['php'], $indent), ";\n"; 
     603                $EX['lastBlock'] = 'basic'; 
    550604            } 
    551605        } 
    552606        if ($curticks) { 
    553             echo $origindent, "}\n"; 
    554         } 
    555     } 
    556     // }}} 
    557     function getOpVal($op, &$EX, $tostr = true, $free = false) // {{{ 
     607            echo $EX['indent'], "}\n"; 
     608        } 
     609    } 
     610    // }}} 
     611    function getOpVal($op, &$EX, $free = false) // {{{ 
    558612    { 
    559613        switch ($op['op_type']) { 
    560614        case XC_IS_CONST: 
    561             return foldToCode(value($op['constant']), $EX); 
     615            return value($op['constant']); 
    562616 
    563617        case XC_IS_VAR: 
     
    565619            $T = &$EX['Ts']; 
    566620            $ret = $T[$op['var']]; 
    567             if ($tostr) { 
    568                 $ret = foldToCode($ret, $EX); 
    569             } 
    570             if ($free) { 
     621            if ($free && empty($this->keepTs)) { 
    571622                unset($T[$op['var']]); 
    572623            } 
     
    598649    function &fixOpcode($opcodes, $removeTailing = false, $defaultReturnValue = null) // {{{ 
    599650    { 
    600         for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) { 
     651        $last = count($opcodes) - 1; 
     652        for ($i = 0; $i <= $last; $i ++) { 
    601653            if (function_exists('xcache_get_fixed_opcode')) { 
    602654                $opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i); 
     
    648700    } 
    649701    // }}} 
     702    function decompileBasicBlock(&$EX, $range, $unhandled = false) // {{{ 
     703    { 
     704        $this->dasmBasicBlock($EX, $range); 
     705        if ($unhandled) { 
     706            $this->dumpRange($EX, $range); 
     707        } 
     708        $this->outputPhp($EX, $range); 
     709    } 
     710    // }}} 
     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    // }}} 
     720    function removeJmpInfo(&$EX, $line) // {{{ 
     721    { 
     722        $opcodes = &$EX['opcodes']; 
     723        foreach ($opcodes[$line]['jmpouts'] as $jmpTo) { 
     724            $jmpins = &$opcodes[$jmpTo]['jmpins']; 
     725            $jmpins = array_flip($jmpins); 
     726            unset($jmpins[$line]); 
     727            $jmpins = array_keys($jmpins); 
     728        } 
     729        // $opcodes[$line]['opcode'] = XC_NOP; 
     730        unset($opcodes[$line]['jmpouts']); 
     731    } 
     732    // }}} 
     733    function beginScope(&$EX, $doIndent = true) // {{{ 
     734    { 
     735        array_push($EX['scopeStack'], array($EX['lastBlock'], $EX['indent'])); 
     736        if ($doIndent) { 
     737            $EX['indent'] .= INDENT; 
     738        } 
     739        $EX['lastBlock'] = null; 
     740    } 
     741    // }}} 
     742    function endScope(&$EX) // {{{ 
     743    { 
     744        list($EX['lastBlock'], $EX['indent']) = array_pop($EX['scopeStack']); 
     745    } 
     746    // }}} 
     747    function beginComplexBlock(&$EX) // {{{ 
     748    { 
     749        if (isset($EX['lastBlock'])) { 
     750            echo PHP_EOL; 
     751            $EX['lastBlock'] = null; 
     752        } 
     753    } 
     754    // }}} 
     755    function endComplexBlock(&$EX) // {{{ 
     756    { 
     757        $EX['lastBlock'] = 'complex'; 
     758    } 
     759    // }}} 
     760    function decompileComplexBlock(&$EX, $range) // {{{ 
     761    { 
     762        $T = &$EX['Ts']; 
     763        $opcodes = &$EX['opcodes']; 
     764        $indent = $EX['indent']; 
     765 
     766        $firstOp = &$opcodes[$range[0]]; 
     767        $lastOp = &$opcodes[$range[1]]; 
     768 
     769        // {{{ && || and or 
     770        if (($firstOp['opcode'] == XC_JMPZ_EX || $firstOp['opcode'] == XC_JMPNZ_EX) && !empty($firstOp['jmpouts']) 
     771         && $firstOp['jmpouts'][0] == $range[1] + 1 
     772         && $lastOp['opcode'] == XC_BOOL 
     773         && $firstOp['opcode']['result']['var'] == $lastOp['opcode']['result']['var'] 
     774        ) { 
     775            $this->removeJmpInfo($EX, $range[0]); 
     776 
     777            $this->recognizeAndDecompileClosedBlocks($EX, array($range[0], $range[0])); 
     778            $op1 = $this->getOpVal($firstOp['result'], $EX, true); 
     779 
     780            $this->recognizeAndDecompileClosedBlocks($EX, array($range[0] + 1, $range[1])); 
     781            $op2 = $this->getOpVal($lastOp['result'], $EX, true); 
     782 
     783            $T[$firstOp['result']['var']] = new Decompiler_Binop($this, $op1, $firstOp['opcode'], $op2); 
     784            return false; 
     785        } 
     786        // }}} 
     787        // {{{ ?: excluding JMP_SET 
     788        if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) 
     789         && $range[1] >= $range[0] + 3 
     790         && $opcodes[$firstOp['jmpouts'][0] - 2]['opcode'] == XC_QM_ASSIGN 
     791         && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $range[1] + 1 
     792         && $lastOp['opcode'] == XC_QM_ASSIGN 
     793        ) { 
     794            $trueRange = array($range[0] + 1, $firstOp['jmpouts'][0] - 2); 
     795            $falseRange = array($firstOp['jmpouts'][0], $range[1]); 
     796            $this->removeJmpInfo($EX, $range[0]); 
     797 
     798            $condition = $this->getOpVal($firstOp['op1'], $EX); 
     799            $this->recognizeAndDecompileClosedBlocks($EX, $trueRange); 
     800            $trueValue = $this->getOpVal($opcodes[$trueRange[1]]['result'], $EX, true); 
     801            $this->recognizeAndDecompileClosedBlocks($EX, $falseRange); 
     802            $falseValue = $this->getOpVal($opcodes[$falseRange[1]]['result'], $EX, true); 
     803            $T[$opcodes[$trueRange[1]]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue); 
     804            return false; 
     805        } 
     806        // }}} 
     807        // {{{ goto 
     808        if ($firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $firstOp['jmpouts'][0] == $range[1] + 1) { 
     809            $this->removeJmpInfo($EX, $range[0]); 
     810            $firstOp['opcode'] = XC_GOTO; 
     811            $target = $firstOp['op1']['var']; 
     812            $firstOp['goto'] = $target; 
     813            $opcodes[$target]['gofrom'][] = $range[0]; 
     814 
     815            $this->recognizeAndDecompileClosedBlocks($EX, $range); 
     816            return false; 
     817        } 
     818        // }}} 
     819        // {{{ for 
     820        if (!empty($firstOp['jmpins']) && $opcodes[$firstOp['jmpins'][0]]['opcode'] == XC_JMP 
     821         && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) && $lastOp['jmpouts'][0] <= $firstOp['jmpins'][0] 
     822         && !empty($opcodes[$range[1] + 1]['jmpins']) && $opcodes[$opcodes[$range[1] + 1]['jmpins'][0]]['opcode'] == XC_JMPZNZ 
     823        ) { 
     824            $nextRange = array($lastOp['jmpouts'][0], $firstOp['jmpins'][0]); 
     825            $conditionRange = array($range[0], $nextRange[0] - 1); 
     826            $this->removeJmpInfo($EX, $conditionRange[1]); 
     827            $bodyRange = array($nextRange[1], $range[1]); 
     828            $this->removeJmpInfo($EX, $bodyRange[1]); 
     829 
     830            $initial = ''; 
     831            $this->beginScope($EX); 
     832            $this->dasmBasicBlock($EX, $conditionRange); 
     833            $conditionCodes = array(); 
     834            for ($i = $conditionRange[0]; $i <= $conditionRange[1]; ++$i) { 
     835                if (isset($opcodes[$i]['php'])) { 
     836                    $conditionCodes[] = str($opcodes[$i]['php'], $EX); 
     837                } 
     838            } 
     839            $conditionCodes[] = str($this->getOpVal($opcodes[$conditionRange[1]]['op1'], $EX), $EX); 
     840            if (implode(',', $conditionCodes) == 'true') { 
     841                $conditionCodes = array(); 
     842            } 
     843            $this->endScope($EX); 
     844 
     845            $this->beginScope($EX); 
     846            $this->dasmBasicBlock($EX, $nextRange); 
     847            $nextCodes = array(); 
     848            for ($i = $nextRange[0]; $i <= $nextRange[1]; ++$i) { 
     849                if (isset($opcodes[$i]['php'])) { 
     850                    $nextCodes[] = str($opcodes[$i]['php'], $EX); 
     851                } 
     852            } 
     853            $this->endScope($EX); 
     854 
     855            $this->beginComplexBlock($EX); 
     856            echo $indent, 'for (', str($initial, $EX), '; ', implode(', ', $conditionCodes), '; ', implode(', ', $nextCodes), ') ', '{', PHP_EOL; 
     857            $this->beginScope($EX); 
     858            $this->recognizeAndDecompileClosedBlocks($EX, $bodyRange); 
     859            $this->endScope($EX); 
     860            echo $indent, '}', PHP_EOL; 
     861            $this->endComplexBlock($EX); 
     862            return; 
     863        } 
     864        // }}} 
     865        // {{{ if/elseif/else 
     866        if ($this->isIfCondition($EX, $range)) { 
     867            $this->beginComplexBlock($EX); 
     868            $isElseIf = false; 
     869            do { 
     870                $ifRange = array($range[0], $opcodes[$range[0]]['jmpouts'][0] - 1); 
     871                $this->removeJmpInfo($EX, $ifRange[0]); 
     872                $this->removeJmpInfo($EX, $ifRange[1]); 
     873                $condition = $this->getOpVal($opcodes[$ifRange[0]]['op1'], $EX); 
     874 
     875                echo $indent, $isElseIf ? 'else if' : 'if', ' (', str($condition, $EX), ') ', '{', PHP_EOL; 
     876                $this->beginScope($EX); 
     877                $this->recognizeAndDecompileClosedBlocks($EX, $ifRange); 
     878                $this->endScope($EX); 
     879                $EX['lastBlock'] = null; 
     880                echo $indent, '}', PHP_EOL; 
     881 
     882                $isElseIf = true; 
     883                // search for else if 
     884                $range[0] = $ifRange[1] + 1; 
     885                for ($i = $ifRange[1] + 1; $i <= $range[1]; ++$i) { 
     886                    // find first jmpout 
     887                    if (!empty($opcodes[$i]['jmpouts'])) { 
     888                        if ($this->isIfCondition($EX, array($i, $range[1]))) { 
     889                            $this->dasmBasicBlock($EX, array($range[0], $i)); 
     890                            $range[0] = $i; 
     891                        } 
     892                        break; 
     893                    } 
     894                } 
     895            } while ($this->isIfCondition($EX, $range)); 
     896            if ($ifRange[1] < $range[1]) { 
     897                $elseRange = array($ifRange[1], $range[1]); 
     898                echo $indent, 'else ', '{', PHP_EOL; 
     899                $this->beginScope($EX); 
     900                $this->recognizeAndDecompileClosedBlocks($EX, $elseRange); 
     901                $this->endScope($EX); 
     902                $EX['lastBlock'] = null; 
     903                echo $indent, '}', PHP_EOL; 
     904            } 
     905            $this->endComplexBlock($EX); 
     906            return; 
     907        } 
     908        // }}} 
     909        // {{{ try/catch 
     910        if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) { 
     911            $catchBlocks = array(); 
     912            $catchFirst = $firstOp['jmpins'][0]; 
     913 
     914            $tryRange = array($range[0], $catchFirst - 1); 
     915 
     916            // search for XC_CATCH 
     917            $this->removeJmpInfo($EX, $catchFirst); 
     918            for ($i = $catchFirst; $i <= $range[1]; ) { 
     919                if ($opcodes[$i]['opcode'] == XC_CATCH) { 
     920                    $catchOpLine = $i; 
     921                    $this->removeJmpInfo($EX, $catchOpLine); 
     922 
     923                    $catchNext = $opcodes[$catchOpLine]['extended_value']; 
     924                    $catchBodyLast = $catchNext - 1; 
     925                    if ($opcodes[$catchBodyLast]['opcode'] == XC_JMP) { 
     926                        --$catchBodyLast; 
     927                    } 
     928 
     929                    $catchBlocks[$catchFirst] = array($catchOpLine, $catchBodyLast); 
     930 
     931                    $i = $catchFirst = $catchNext; 
     932                } 
     933                else { 
     934                    ++$i; 
     935                } 
     936            } 
     937 
     938            if ($opcodes[$tryRange[1]]['opcode'] == XC_JMP) { 
     939                --$tryRange[1]; 
     940            } 
     941 
     942            $this->beginComplexBlock($EX); 
     943            echo $indent, "try {", PHP_EOL; 
     944            $this->beginScope($EX); 
     945            $this->recognizeAndDecompileClosedBlocks($EX, $tryRange); 
     946            $this->endScope($EX); 
     947            echo $indent, '}', PHP_EOL; 
     948            foreach ($catchBlocks as $catchFirst => $catchInfo) { 
     949                list($catchOpLine, $catchBodyLast) = $catchInfo; 
     950                $catchBodyFirst = $catchOpLine + 1; 
     951                $this->dasmBasicBlock($EX, array($catchFirst, $catchOpLine)); 
     952                $catchOp = &$opcodes[$catchOpLine]; 
     953                echo $indent, 'catch (', str($this->getOpVal($catchOp['op1'], $EX)), ' ', str($this->getOpVal($catchOp['op2'], $EX)), ") {", PHP_EOL; 
     954                unset($catchOp); 
     955 
     956                $EX['lastBlock'] = null; 
     957                $this->beginScope($EX); 
     958                $this->recognizeAndDecompileClosedBlocks($EX, array($catchBodyFirst, $catchBodyLast)); 
     959                $this->endScope($EX); 
     960                echo $indent, '}', PHP_EOL; 
     961            } 
     962            $this->endComplexBlock($EX); 
     963            return; 
     964        } 
     965        // }}} 
     966        // {{{ switch/case 
     967        if ($firstOp['opcode'] == XC_SWITCH_FREE && isset($T[$firstOp['op1']['var']])) { 
     968            // TODO: merge this code to CASE code. use SWITCH_FREE to detect begin of switch by using $Ts if possible 
     969            $this->beginComplexBlock($EX); 
     970            echo $indent, 'switch (', str($this->getOpVal($firstOp['op1'], $EX)), ") {", PHP_EOL; 
     971            echo $indent, '}', PHP_EOL; 
     972            $this->endComplexBlock($EX); 
     973            return; 
     974        } 
     975 
     976        if ( 
     977            ($firstOp['opcode'] == XC_CASE 
     978            || $firstOp['opcode'] == XC_JMP && !empty($firstOp['jmpouts']) && $opcodes[$firstOp['jmpouts'][0]]['opcode'] == XC_CASE 
     979            ) 
     980             && !empty($lastOp['jmpouts']) 
     981        ) { 
     982            $cases = array(); 
     983            $caseDefault = null; 
     984            $caseOp = null; 
     985            for ($i = $range[0]; $i <= $range[1]; ) { 
     986                $op = $opcodes[$i]; 
     987                if ($op['opcode'] == XC_CASE) { 
     988                    if (!isset($caseOp)) { 
     989                        $caseOp = $op; 
     990                    } 
     991                    $jmpz = $opcodes[$i + 1]; 
     992                    assert('$jmpz["opcode"] == XC_JMPZ'); 
     993                    $caseNext = $jmpz['jmpouts'][0]; 
     994                    $cases[$i] = $caseNext - 1; 
     995                    $i = $caseNext; 
     996                } 
     997                else if ($op['opcode'] == XC_JMP && $op['jmpouts'][0] >= $i) { 
     998                    // default 
     999                    $caseNext = $op['jmpouts'][0]; 
     1000                    $caseDefault = $i; 
     1001                    $cases[$i] = $caseNext - 1; 
     1002                    $i = $caseNext; 
     1003                } 
     1004                else { 
     1005                    ++$i; 
     1006                } 
     1007            } 
     1008 
     1009            $this->beginComplexBlock($EX); 
     1010 
     1011            echo $indent, 'switch (', str($this->getOpVal($caseOp['op1'], $EX), $EX), ") {", PHP_EOL; 
     1012            $caseIsOut = false; 
     1013            foreach ($cases as $caseFirst => $caseLast) { 
     1014                if ($caseIsOut && empty($lastCaseFall)) { 
     1015                    echo PHP_EOL; 
     1016                } 
     1017 
     1018                $caseOp = $opcodes[$caseFirst]; 
     1019 
     1020                echo $indent; 
     1021                if ($caseOp['opcode'] == XC_CASE) { 
     1022                    echo 'case '; 
     1023                    echo str($this->getOpVal($caseOp['op2'], $EX), $EX); 
     1024                    echo ':', PHP_EOL; 
     1025 
     1026                    $this->removeJmpInfo($EX, $caseFirst); 
     1027                    ++$caseFirst; 
     1028 
     1029                    assert('$opcodes[$caseFirst]["opcode"] == XC_JMPZ'); 
     1030                    $this->removeJmpInfo($EX, $caseFirst); 
     1031                    ++$caseFirst; 
     1032                } 
     1033                else { 
     1034                    echo 'default'; 
     1035                    echo ':', PHP_EOL; 
     1036 
     1037                    assert('$opcodes[$caseFirst]["opcode"] == XC_JMP'); 
     1038                    $this->removeJmpInfo($EX, $caseFirst); 
     1039                    ++$caseFirst; 
     1040                } 
     1041 
     1042                assert('$opcodes[$caseLast]["opcode"] == XC_JMP'); 
     1043                $this->removeJmpInfo($EX, $caseLast); 
     1044                --$caseLast; 
     1045                switch ($opcodes[$caseLast]['opcode']) { 
     1046                case XC_BRK: 
     1047                case XC_CONT: 
     1048                case XC_GOTO: 
     1049                    $lastCaseFall = false; 
     1050                    break; 
     1051 
     1052                default: 
     1053                    $lastCaseFall = true; 
     1054                } 
     1055 
     1056                $this->beginScope($EX); 
     1057                $this->recognizeAndDecompileClosedBlocks($EX, array($caseFirst, $caseLast)); 
     1058                $this->endScope($EX); 
     1059                $caseIsOut = true; 
     1060            } 
     1061            echo $indent, '}', PHP_EOL; 
     1062 
     1063            $this->endComplexBlock($EX); 
     1064            return; 
     1065        } 
     1066        // }}} 
     1067        // {{{ do/while 
     1068        if ($lastOp['opcode'] == XC_JMPNZ && !empty($lastOp['jmpouts']) 
     1069         && $lastOp['jmpouts'][0] == $range[0]) { 
     1070            $this->removeJmpInfo($EX, $range[1]); 
     1071            $this->beginComplexBlock($EX); 
     1072 
     1073            echo $indent, "do {", PHP_EOL; 
     1074            $this->beginScope($EX); 
     1075            $this->recognizeAndDecompileClosedBlocks($EX, $range); 
     1076            $this->endScope($EX); 
     1077            echo $indent, "} while (", str($this->getOpVal($lastOp['op1'], $EX)), ');', PHP_EOL; 
     1078 
     1079            $this->endComplexBlock($EX); 
     1080            return; 
     1081        } 
     1082        // }}} 
     1083 
     1084        // {{{ search firstJmpOp 
     1085        $firstJmp = null; 
     1086        $firstJmpOp = null; 
     1087        for ($i = $range[0]; $i <= $range[1]; ++$i) { 
     1088            if (!empty($opcodes[$i]['jmpouts'])) { 
     1089                $firstJmp = $i; 
     1090                $firstJmpOp = &$opcodes[$firstJmp]; 
     1091                break; 
     1092            } 
     1093        } 
     1094        // }}} 
     1095 
     1096        // {{{ while 
     1097        if (isset($firstJmpOp) 
     1098         && $firstJmpOp['opcode'] == XC_JMPZ 
     1099         && $firstJmpOp['jmpouts'][0] > $range[1] 
     1100         && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) 
     1101         && $lastOp['jmpouts'][0] == $range[0]) { 
     1102            $this->removeJmpInfo($EX, $firstJmp); 
     1103            $this->removeJmpInfo($EX, $range[1]); 
     1104            $this->beginComplexBlock($EX); 
     1105 
     1106            ob_start(); 
     1107            $this->beginScope($EX); 
     1108            $this->recognizeAndDecompileClosedBlocks($EX, $range); 
     1109            $this->endScope($EX); 
     1110            $body = ob_get_clean(); 
     1111 
     1112            echo $indent, 'while (', str($this->getOpVal($firstJmpOp['op1'], $EX)), ") {", PHP_EOL; 
     1113            echo $body; 
     1114            echo $indent, '}', PHP_EOL; 
     1115 
     1116            $this->endComplexBlock($EX); 
     1117            return; 
     1118        } 
     1119        // }}} 
     1120        // {{{ foreach 
     1121        if (isset($firstJmpOp) 
     1122         && $firstJmpOp['opcode'] == XC_FE_FETCH 
     1123         && $firstJmpOp['jmpouts'][0] > $range[1] 
     1124         && $lastOp['opcode'] == XC_JMP && !empty($lastOp['jmpouts']) 
     1125         && $lastOp['jmpouts'][0] == $firstJmp) { 
     1126            $this->removeJmpInfo($EX, $firstJmp); 
     1127            $this->removeJmpInfo($EX, $range[1]); 
     1128            $this->beginComplexBlock($EX); 
     1129 
     1130            ob_start(); 
     1131            $this->beginScope($EX); 
     1132            $this->recognizeAndDecompileClosedBlocks($EX, $range); 
     1133            $this->endScope($EX); 
     1134            $body = ob_get_clean(); 
     1135 
     1136            $as = foldToCode($firstJmpOp['fe_as'], $EX); 
     1137            if (isset($firstJmpOp['fe_key'])) { 
     1138                $as = str($firstJmpOp['fe_key'], $EX) . ' => ' . str($as); 
     1139            } 
     1140 
     1141            echo $indent, 'foreach (', str($firstJmpOp['fe_src'], $EX), " as $as) {", PHP_EOL; 
     1142            echo $body; 
     1143            echo $indent, '}', PHP_EOL; 
     1144 
     1145            $this->endComplexBlock($EX); 
     1146            if ($opcodes[$range[1] + 1]['opcode'] == XC_SWITCH_FREE) { 
     1147                $this->removeJmpInfo($EX, $range[1] + 1); 
     1148            } 
     1149            return; 
     1150        } 
     1151        // }}} 
     1152 
     1153        $this->decompileBasicBlock($EX, $range, true); 
     1154    } 
     1155    // }}} 
     1156    function recognizeAndDecompileClosedBlocks(&$EX, $range) // {{{ decompile in a tree way 
     1157    { 
     1158        $opcodes = &$EX['opcodes']; 
     1159 
     1160        $starti = $range[0]; 
     1161        for ($i = $starti; $i <= $range[1]; ) { 
     1162            if (!empty($opcodes[$i]['jmpins']) || !empty($opcodes[$i]['jmpouts'])) { 
     1163                $blockFirst = $i; 
     1164                $blockLast = -1; 
     1165                $j = $blockFirst; 
     1166                do { 
     1167                    $op = $opcodes[$j]; 
     1168                    if (!empty($op['jmpins'])) { 
     1169                        // care about jumping from blocks behind, not before 
     1170                        foreach ($op['jmpins'] as $oplineNumber) { 
     1171                            if ($oplineNumber <= $range[1] && $blockLast < $oplineNumber) { 
     1172                                $blockLast = $oplineNumber; 
     1173                            } 
     1174                        } 
     1175                    } 
     1176                    if (!empty($op['jmpouts'])) { 
     1177                        $blockLast = max($blockLast, max($op['jmpouts']) - 1); 
     1178                    } 
     1179                    ++$j; 
     1180                } while ($j <= $blockLast); 
     1181                if (!assert('$blockLast <= $range[1]')) { 
     1182                    var_dump($blockLast, $range[1]); 
     1183                } 
     1184 
     1185                if ($blockLast >= $blockFirst) { 
     1186                    if ($blockFirst > $starti) { 
     1187                        $this->decompileBasicBlock($EX, array($starti, $blockFirst - 1)); 
     1188                    } 
     1189                    if ($this->decompileComplexBlock($EX, array($blockFirst, $blockLast)) === false) { 
     1190                        if ($EX['lastBlock'] == 'complex') { 
     1191                            echo PHP_EOL; 
     1192                        } 
     1193                        $EX['lastBlock'] = null; 
     1194                    } 
     1195                    $starti = $blockLast + 1; 
     1196                    $i = $starti; 
     1197                } 
     1198                else { 
     1199                    ++$i; 
     1200                } 
     1201            } 
     1202            else { 
     1203                ++$i; 
     1204            } 
     1205        } 
     1206        if ($starti <= $range[1]) { 
     1207            $this->decompileBasicBlock($EX, array($starti, $range[1])); 
     1208        } 
     1209    } 
     1210    // }}} 
    6501211    function &dop_array($op_array, $indent = '') // {{{ 
    6511212    { 
    6521213        $op_array['opcodes'] = $this->fixOpcode($op_array['opcodes'], true, $indent == '' ? 1 : null); 
    6531214        $opcodes = &$op_array['opcodes']; 
    654         $EX['indent'] = ''; 
    655         // {{{ build jmp array 
    656         for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) { 
     1215        $last = count($opcodes) - 1; 
     1216        // {{{ build jmpins/jmpouts to op_array 
     1217        for ($i = 0; $i <= $last; $i ++) { 
    6571218            $op = &$opcodes[$i]; 
    658             /* 
    659             if ($op['opcode'] == XC_JMPZ) { 
    660                 $this->dumpop($op, $EX); 
    661                 var_dump($op); 
    662             } 
    663             continue; 
    664             */ 
    6651219            $op['line'] = $i; 
    6661220            switch ($op['opcode']) { 
     
    6711225 
    6721226            case XC_GOTO: 
     1227                $target = $op['op1']['var']; 
     1228                $op['goto'] = $target; 
     1229                $opcodes[$target]['gofrom'][] = $i; 
     1230                break; 
     1231 
    6731232            case XC_JMP: 
    6741233                $target = $op['op1']['var']; 
     
    6891248            case XC_JMPZ_EX: 
    6901249            case XC_JMPNZ_EX: 
    691             case XC_JMP_SET: 
     1250            // case XC_JMP_SET: 
    6921251            // case XC_FE_RESET: 
    6931252            case XC_FE_FETCH: 
     
    7071266                break; 
    7081267            */ 
    709             } 
     1268 
     1269            case XC_SWITCH_FREE: 
     1270                $op['jmpouts'] = array($i + 1); 
     1271                $opcodes[$i + 1]['jmpins'][] = $i; 
     1272                break; 
     1273 
     1274            case XC_CASE: 
     1275                // just to link together 
     1276                $op['jmpouts'] = array($i + 2); 
     1277                $opcodes[$i + 2]['jmpins'][] = $i; 
     1278                break; 
     1279 
     1280            case XC_CATCH: 
     1281                $catchNext = $op['extended_value']; 
     1282                $op['jmpouts'] = array($catchNext); 
     1283                $opcodes[$catchNext]['jmpins'][] = $i; 
     1284                break; 
     1285            } 
     1286            /* 
     1287            if (!empty($op['jmpouts']) || !empty($op['jmpins'])) { 
     1288                echo $i, "\t", xcache_get_opcode($op['opcode']), PHP_EOL; 
     1289            } 
     1290            // */ 
    7101291        } 
    7111292        unset($op); 
     1293        if ($op_array['try_catch_array']) { 
     1294            foreach ($op_array['try_catch_array'] as $try_catch_element) { 
     1295                $catch_op = $try_catch_element['catch_op']; 
     1296                $try_op = $try_catch_element['try_op']; 
     1297                $opcodes[$try_op]['jmpins'][] = $catch_op; 
     1298                $opcodes[$catch_op]['jmpouts'][] = $try_op; 
     1299                $opcodes[$catch_op]['isCatchBegin'] = true; 
     1300            } 
     1301        } 
    7121302        // }}} 
    7131303        // build semi-basic blocks 
    7141304        $nextbbs = array(); 
    7151305        $starti = 0; 
    716         for ($i = 1, $cnt = count($opcodes); $i < $cnt; $i ++) { 
     1306        for ($i = 1; $i <= $last; $i ++) { 
    7171307            if (isset($opcodes[$i]['jmpins']) 
    7181308             || isset($opcodes[$i - 1]['jmpouts'])) { 
     
    7211311            } 
    7221312        } 
    723         $nextbbs[$starti] = $cnt; 
     1313        $nextbbs[$starti] = $last + 1; 
    7241314 
    7251315        $EX = array(); 
     
    7291319        $EX['op_array'] = &$op_array; 
    7301320        $EX['opcodes'] = &$opcodes; 
     1321        $EX['range'] = array(0, count($opcodes) - 1); 
    7311322        // func call 
    7321323        $EX['object'] = null; 
     
    7351326        $EX['argstack'] = array(); 
    7361327        $EX['arg_types_stack'] = array(); 
    737         $EX['last'] = count($opcodes) - 1; 
     1328        $EX['scopeStack'] = array(); 
    7381329        $EX['silence'] = 0; 
    7391330        $EX['recvs'] = array(); 
    7401331        $EX['uses'] = array(); 
    741  
    742         for ($next = 0, $last = $EX['last']; 
    743                 $loop = $this->outputCode($EX, $next, $last, $indent, true); 
    744                 list($next, $last) = $loop) { 
    745             // empty 
    746         } 
     1332        $EX['lastBlock'] = null; 
     1333 
     1334        /* dump whole array 
     1335        $this->keepTs = true; 
     1336        $this->dasmBasicBlock($EX, $range); 
     1337        for ($i = $range[0]; $i <= $range[1]; ++$i) { 
     1338            echo $i, "\t", $this->dumpop($opcodes[$i], $EX); 
     1339        } 
     1340        // */ 
     1341        // decompile in a tree way 
     1342        $this->recognizeAndDecompileClosedBlocks($EX, $EX['range'], $EX['indent']); 
    7471343        return $EX; 
    7481344    } 
    7491345    // }}} 
    750     function outputCode(&$EX, $opline, $last, $indent, $loop = false) // {{{ 
    751     { 
    752         $op = &$EX['opcodes'][$opline]; 
    753         $next = $EX['nextbbs'][$opline]; 
    754  
    755         $end = $next - 1; 
    756         if ($end > $last) { 
    757             $end = $last; 
    758         } 
    759  
    760         if (isset($op['jmpins'])) { 
    761             echo "\nline", $op['line'], ":\n"; 
    762         } 
    763         else { 
    764             // echo ";;;\n"; 
    765         } 
    766         $this->dasmBasicBlock($EX, $opline, $end); 
    767         $this->outputPhp($EX['opcodes'], $opline, $end, $indent); 
    768         // jmpout op 
    769         $op = &$EX['opcodes'][$end]; 
    770         $op1 = $op['op1']; 
    771         $op2 = $op['op2']; 
    772         $ext = $op['extended_value']; 
    773         $line = $op['line']; 
    774  
    775         if (isset($EX['opcodes'][$next])) { 
    776             if (isset($last) && $next > $last) { 
    777                 $next = null; 
    778             } 
    779         } 
    780         else { 
    781             $next = null; 
    782         } 
    783         if ($op['opcode'] == XC_FE_FETCH) { 
    784             $opline = $next; 
    785             $next = $op['op2']['opline_num']; 
    786             $end = $next - 1; 
    787  
    788             ob_start(); 
    789             $this->outputCode($EX, $opline, $end /* - 1 skip last jmp */, $indent . INDENT); 
    790             $body = ob_get_clean(); 
    791  
    792             $as = foldToCode($op['fe_as'], $EX); 
    793             if (isset($op['fe_key'])) { 
    794                 $as = str($op['fe_key'], $EX) . ' => ' . str($as); 
    795             } 
    796             echo "{$indent}foreach (" . str($op['fe_src'], $EX) . " as $as) {\n"; 
    797             echo $body; 
    798             echo "{$indent}}"; 
    799             // $this->outputCode($EX, $next, $last, $indent); 
    800             // return; 
    801         } 
    802         /* 
    803         if ($op['opcode'] == XC_JMPZ) { 
    804             $target = $op2['opline_num']; 
    805             if ($line + 1) { 
    806                 $nextblock = $EX['nextbbs'][$next]; 
    807                 $jmpop = end($nextblock); 
    808                 if ($jmpop['opcode'] == XC_JMP) { 
    809                     $ifendline = $op2['opline_num']; 
    810                     if ($ifendline >= $line) { 
    811                         $cond = $op['cond']; 
    812                         echo "{$indent}if ($cond) {\n"; 
    813                         $this->outputCode($EX, $next, $last, INDENT . $indent); 
    814                         echo "$indent}\n"; 
    815                         $this->outputCode($EX, $target, $last, $indent); 
    816                         return; 
    817                     } 
    818                 } 
    819             } 
    820         } 
    821         */ 
    822         if (!isset($next)) { 
    823             return; 
    824         } 
    825         if (isset($op['jmpouts']) && isset($op['isjmp'])) { 
    826             if (isset($op['cond'])) { 
    827                 echo "{$indent}check (" . str($op["cond"]) . ") {\n"; 
    828                 echo INDENT; 
    829             } 
    830             switch ($op['opcode']) { 
    831             case XC_CONT: 
    832             case XC_BRK: 
    833                 break; 
    834  
    835             case XC_GOTO: 
    836                 echo $indent, 'goto', ' line', $op['jmpouts'][0], ';', "\n"; 
    837                 break; 
    838  
    839             default: 
    840                 echo $indent; 
    841                 echo xcache_get_opcode($op['opcode']), ' line', $op['jmpouts'][0]; 
    842                 if (isset($op['jmpouts'][1])) { 
    843                     echo ', line', $op['jmpouts'][1]; 
    844                 } 
    845                 echo ";"; 
    846                 // echo ' // <- line', $op['line']; 
    847                 echo "\n"; 
    848             } 
    849             if (isset($op['cond'])) echo "$indent}\n"; 
    850         } 
    851  
    852         // proces JMPZ_EX/JMPNZ_EX for AND,OR 
    853         $op = &$EX['opcodes'][$next]; 
    854         /* 
    855         if (isset($op['jmpins'])) { 
    856             foreach (array_reverse($op['jmpins']) as $fromline) { 
    857                 $fromop = $EX['opcodes'][$fromline]; 
    858                 switch ($fromop['opcode']) { 
    859                 case XC_JMPZ_EX: $opstr = 'and'; break; 
    860                 case XC_JMPNZ_EX: $opstr = 'or'; break; 
    861                 case XC_JMPZNZ: var_dump($fromop); exit; 
    862                 default: continue 2; 
    863                 } 
    864  
    865                 $var = $fromop['result']['var']; 
    866                 var_dump($EX['Ts'][$var]); 
    867                 $EX['Ts'][$var] = '(' . $fromop['and_or'] . " $opstr " . $EX['Ts'][$var] . ')'; 
    868             } 
    869             #$this->outputCode($EX, $next, $last, $indent); 
    870             #return; 
    871         } 
    872         */ 
    873         if (isset($op['cond_false'])) { 
    874             // $this->dumpop($op, $EX); 
    875             // any true comes here, so it's a "or" 
    876             $cond = implode(' and ', str($op['cond_false'])); 
    877             // var_dump($op['cond'] = $cond); 
    878             /* 
    879             $rvalue = implode(' or ', $op['cond_true']) . ' or ' . $rvalue; 
    880             unset($op['cond_true']); 
    881             */ 
    882         } 
    883  
    884         if ($loop) { 
    885             return array($next, $last); 
    886         } 
    887         $this->outputCode($EX, $next, $last, $indent); 
    888     } 
    889     // }}} 
    890     function dasmBasicBlock(&$EX, $opline, $last) // {{{ 
     1346    function dasmBasicBlock(&$EX, $range) // {{{ 
    8911347    { 
    8921348        $T = &$EX['Ts']; 
     
    8941350        $lastphpop = null; 
    8951351 
    896         for ($i = $opline, $ic = $last + 1; $i < $ic; $i ++) { 
     1352        for ($i = $range[0]; $i <= $range[1]; $i ++) { 
    8971353            // {{{ prepair 
    8981354            $op = &$opcodes[$i]; 
     
    9181374 
    9191375            $resvar = null; 
     1376            unset($curResVar); 
     1377            if (array_key_exists($res['var'], $T)) { 
     1378                $curResVar = &$T[$res['var']]; 
     1379            } 
    9201380            if ((ZEND_ENGINE_2_4 ? ($res['op_type'] & EXT_TYPE_UNUSED) : ($res['EA.type'] & EXT_TYPE_UNUSED)) || $res['op_type'] == XC_IS_UNUSED) { 
    9211381                $istmpres = false; 
     
    9271387            // echo $opname, "\n"; 
    9281388 
    929             $call = array(&$this, $opname); 
    930             if (is_callable($call)) { 
    931                 $this->usedOps[$opc] = true; 
    932                 $this->{$opname}($op, $EX); 
    933             } 
    934             else if (isset($this->binops[$opc])) { // {{{ 
    935                 $this->usedOps[$opc] = true; 
    936                 $op1val = $this->getOpVal($op1, $EX, false); 
    937                 $op2val = $this->getOpVal($op2, $EX, false); 
    938                 $rvalue = new Decompiler_Binop($this, $op1val, $opc, $op2val); 
    939                 $resvar = $rvalue; 
    940                 // }}} 
    941             } 
    942             else if (isset($this->unaryops[$opc])) { // {{{ 
    943                 $this->usedOps[$opc] = true; 
    944                 $op1val = $this->getOpVal($op1, $EX); 
    945                 $myop = $this->unaryops[$opc]; 
    946                 $rvalue = $myop . str($op1val); 
    947                 $resvar = $rvalue; 
    948                 // }}} 
    949             } 
    950             else { 
    951                 $covered = true; 
    952                 switch ($opc) { 
    953                 case XC_NEW: // {{{ 
    954                     array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope'])); 
    955                     $EX['object'] = (int) $res['var']; 
    956                     $EX['called_scope'] = null; 
    957                     $EX['fbc'] = 'new ' . unquoteName($this->getOpVal($op1, $EX), $EX); 
    958                     if (!ZEND_ENGINE_2) { 
    959                         $resvar = '$new object$'; 
    960                     } 
     1389            $notHandled = false; 
     1390            switch ($opc) { 
     1391            case XC_NEW: // {{{ 
     1392                array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope'])); 
     1393                $EX['object'] = (int) $res['var']; 
     1394                $EX['called_scope'] = null; 
     1395                $EX['fbc'] = 'new ' . unquoteName($this->getOpVal($op1, $EX), $EX); 
     1396                if (!ZEND_ENGINE_2) { 
     1397                    $resvar = '$new object$'; 
     1398                } 
     1399                break; 
     1400                // }}} 
     1401            case XC_THROW: // {{{ 
     1402                $resvar = 'throw ' . str($this->getOpVal($op1, $EX)); 
     1403                break; 
     1404                // }}} 
     1405            case XC_CLONE: // {{{ 
     1406                $resvar = 'clone ' . str($this->getOpVal($op1, $EX)); 
     1407                break; 
     1408                // }}} 
     1409            case XC_CATCH: // {{{ 
     1410                break; 
     1411                // }}} 
     1412            case XC_INSTANCEOF: // {{{ 
     1413                $resvar = str($this->getOpVal($op1, $EX)) . ' instanceof ' . str($this->getOpVal($op2, $EX)); 
     1414                break; 
     1415                // }}} 
     1416            case XC_FETCH_CLASS: // {{{ 
     1417                if ($op2['op_type'] == XC_IS_UNUSED) { 
     1418                    switch (($ext & (defined('ZEND_FETCH_CLASS_MASK') ? ZEND_FETCH_CLASS_MASK : 0xFF))) { 
     1419                    case ZEND_FETCH_CLASS_SELF: 
     1420                        $class = 'self'; 
     1421                        break; 
     1422                    case ZEND_FETCH_CLASS_PARENT: 
     1423                        $class = 'parent'; 
     1424                        break; 
     1425                    case ZEND_FETCH_CLASS_STATIC: 
     1426                        $class = 'static'; 
     1427                        break; 
     1428                    } 
     1429                    $istmpres = true; 
     1430                } 
     1431                else { 
     1432                    $class = $this->getOpVal($op2, $EX); 
     1433                    if (isset($op2['constant'])) { 
     1434                        $class = $this->stripNamespace(unquoteName($class)); 
     1435                    } 
     1436                } 
     1437                $resvar = $class; 
     1438                break; 
     1439                // }}} 
     1440            case XC_FETCH_CONSTANT: // {{{ 
     1441                if ($op1['op_type'] == XC_IS_UNUSED) { 
     1442                    $resvar = $this->stripNamespace($op2['constant']); 
    9611443                    break; 
    962                     // }}} 
    963                 case XC_THROW: // {{{ 
    964                     $resvar = 'throw ' . str($this->getOpVal($op1, $EX)); 
     1444                } 
     1445 
     1446                if ($op1['op_type'] == XC_IS_CONST) { 
     1447                    $resvar = $this->stripNamespace($op1['constant']); 
     1448                } 
     1449                else { 
     1450                    $resvar = $this->getOpVal($op1, $EX); 
     1451                } 
     1452 
     1453                $resvar = str($resvar) . '::' . unquoteName($this->getOpVal($op2, $EX)); 
     1454                break; 
     1455                // }}} 
     1456                // {{{ case XC_FETCH_* 
     1457            case XC_FETCH_R: 
     1458            case XC_FETCH_W: 
     1459            case XC_FETCH_RW: 
     1460            case XC_FETCH_FUNC_ARG: 
     1461            case XC_FETCH_UNSET: 
     1462            case XC_FETCH_IS: 
     1463            case XC_UNSET_VAR: 
     1464                $rvalue = $this->getOpVal($op1, $EX); 
     1465                if (defined('ZEND_FETCH_TYPE_MASK')) { 
     1466                    $fetchtype = ($ext & ZEND_FETCH_TYPE_MASK); 
     1467                } 
     1468                else { 
     1469                    $fetchtype = $op2[!ZEND_ENGINE_2 ? 'fetch_type' : 'EA.type']; 
     1470                } 
     1471                switch ($fetchtype) { 
     1472                case ZEND_FETCH_STATIC_MEMBER: 
     1473                    $class = $this->getOpVal($op2, $EX); 
     1474                    $rvalue = str($class) . '::$' . unquoteName($rvalue, $EX); 
    9651475                    break; 
    966                     // }}} 
    967                 case XC_CLONE: // {{{ 
    968                     $resvar = 'clone ' . str($this->getOpVal($op1, $EX)); 
     1476                default: 
     1477                    $name = unquoteName($rvalue, $EX); 
     1478                    $globalname = xcache_is_autoglobal($name) ? "\$$name" : "\$GLOBALS[" . str($rvalue) . "]"; 
     1479                    $rvalue = new Decompiler_Fetch($rvalue, $fetchtype, $globalname); 
    9691480                    break; 
    970                     // }}} 
    971                 case XC_CATCH: // {{{ 
    972                     $resvar = 'catch (' . str($this->getOpVal($op1, $EX)) . ' ' . str($this->getOpVal($op2, $EX)) . ')'; 
     1481                } 
     1482                if ($opc == XC_UNSET_VAR) { 
     1483                    $op['php'] = "unset(" . str($rvalue, $EX) . ")"; 
     1484                    $lastphpop = &$op; 
     1485                } 
     1486                else if ($res['op_type'] != XC_IS_UNUSED) { 
     1487                    $resvar = $rvalue; 
     1488                } 
     1489                break; 
     1490                // }}} 
     1491                // {{{ case XC_FETCH_DIM_* 
     1492            case XC_FETCH_DIM_TMP_VAR: 
     1493            case XC_FETCH_DIM_R: 
     1494            case XC_FETCH_DIM_W: 
     1495            case XC_FETCH_DIM_RW: 
     1496            case XC_FETCH_DIM_FUNC_ARG: 
     1497            case XC_FETCH_DIM_UNSET: 
     1498            case XC_FETCH_DIM_IS: 
     1499            case XC_ASSIGN_DIM: 
     1500            case XC_UNSET_DIM_OBJ: // PHP 4 only 
     1501            case XC_UNSET_DIM: 
     1502            case XC_UNSET_OBJ: 
     1503                $src = $this->getOpVal($op1, $EX); 
     1504                if (is_a($src, "Decompiler_ForeachBox")) { 
     1505                    $src->iskey = $this->getOpVal($op2, $EX); 
     1506                    $resvar = $src; 
    9731507                    break; 
    974                     // }}} 
    975                 case XC_INSTANCEOF: // {{{ 
    976                     $resvar = str($this->getOpVal($op1, $EX)) . ' instanceof ' . str($this->getOpVal($op2, $EX)); 
     1508                } 
     1509 
     1510                if (is_a($src, "Decompiler_DimBox")) { 
     1511                    $dimbox = $src; 
     1512                } 
     1513                else { 
     1514                    if (!is_a($src, "Decompiler_ListBox")) { 
     1515                        $op1val = $this->getOpVal($op1, $EX); 
     1516                        $list = new Decompiler_List(isset($op1val) ? $op1val : '$this'); 
     1517 
     1518                        $src = new Decompiler_ListBox($list); 
     1519                        if (!isset($op1['var'])) { 
     1520                            $this->dumpop($op, $EX); 
     1521                            var_dump($op); 
     1522                            die('missing var'); 
     1523                        } 
     1524                        $T[$op1['var']] = $src; 
     1525                        unset($list); 
     1526                    } 
     1527                    $dim = new Decompiler_Dim($src); 
     1528                    $src->obj->dims[] = &$dim; 
     1529 
     1530                    $dimbox = new Decompiler_DimBox($dim); 
     1531                } 
     1532                $dim = &$dimbox->obj; 
     1533                $dim->offsets[] = $this->getOpVal($op2, $EX); 
     1534                if ($ext == ZEND_FETCH_ADD_LOCK) { 
     1535                    $src->obj->everLocked = true; 
     1536                } 
     1537                else if ($ext == ZEND_FETCH_STANDARD) { 
     1538                    $dim->isLast = true; 
     1539                } 
     1540                if ($opc == XC_UNSET_OBJ) { 
     1541                    $dim->isObject = true; 
     1542                } 
     1543                unset($dim); 
     1544                $rvalue = $dimbox; 
     1545                unset($dimbox); 
     1546 
     1547                if ($opc == XC_ASSIGN_DIM) { 
     1548                    $lvalue = $rvalue; 
     1549                    ++ $i; 
     1550                    $rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX); 
     1551                    $resvar = str($lvalue, $EX) . ' = ' . str($rvalue); 
     1552                } 
     1553                else if ($opc == XC_UNSET_DIM || $opc == XC_UNSET_OBJ) { 
     1554                    $op['php'] = "unset(" . str($rvalue, $EX) . ")"; 
     1555                    $lastphpop = &$op; 
     1556                } 
     1557                else if ($res['op_type'] != XC_IS_UNUSED) { 
     1558                    $resvar = $rvalue; 
     1559                } 
     1560                break; 
     1561                // }}} 
     1562            case XC_ASSIGN: // {{{ 
     1563                $lvalue = $this->getOpVal($op1, $EX); 
     1564                $rvalue = $this->getOpVal($op2, $EX); 
     1565                if (is_a($rvalue, 'Decompiler_ForeachBox')) { 
     1566                    $type = $rvalue->iskey ? 'fe_key' : 'fe_as'; 
     1567                    $rvalue->obj[$type] = $lvalue; 
     1568                    unset($T[$op2['var']]); 
    9771569                    break; 
    978                     // }}} 
    979                 case XC_FETCH_CLASS: // {{{ 
    980                     if ($op2['op_type'] == XC_IS_UNUSED) { 
    981                         switch (($ext & (defined('ZEND_FETCH_CLASS_MASK') ? ZEND_FETCH_CLASS_MASK : 0xFF))) { 
    982                         case ZEND_FETCH_CLASS_SELF: 
    983                             $class = 'self'; 
    984                             break; 
    985                         case ZEND_FETCH_CLASS_PARENT: 
    986                             $class = 'parent'; 
    987                             break; 
    988                         case ZEND_FETCH_CLASS_STATIC: 
    989                             $class = 'static'; 
    990                             break; 
    991                         } 
    992                         $istmpres = true; 
    993                     } 
    994                     else { 
    995                         $class = $this->getOpVal($op2, $EX); 
    996                         if (isset($op2['constant'])) { 
    997                             $class = $this->stripNamespace(unquoteName($class)); 
    998                         } 
    999                     } 
    1000                     $resvar = $class; 
     1570                } 
     1571                if (is_a($rvalue, "Decompiler_DimBox")) { 
     1572                    $dim = &$rvalue->obj; 
     1573                    $dim->assign = $lvalue; 
     1574                    if ($dim->isLast) { 
     1575                        $resvar = foldToCode($dim->value, $EX); 
     1576                    } 
     1577                    unset($dim); 
    10011578                    break; 
    1002                     // }}} 
    1003                 case XC_FETCH_CONSTANT: // {{{ 
    1004                     if ($op1['op_type'] == XC_IS_UNUSED) { 
    1005                         $resvar = $this->stripNamespace($op2['constant']); 
    1006                         break; 
    1007                     } 
    1008  
    1009                     if ($op1['op_type'] == XC_IS_CONST) { 
    1010                         $resvar = $this->stripNamespace($op1['constant']); 
    1011                     } 
    1012                     else { 
    1013                         $resvar = $this->getOpVal($op1, $EX); 
    1014                     } 
    1015  
    1016                     $resvar = str($resvar) . '::' . unquoteName($this->getOpVal($op2, $EX)); 
    1017                     break; 
    1018                     // }}} 
    1019                     // {{{ case XC_FETCH_* 
    1020                 case XC_FETCH_R: 
    1021                 case XC_FETCH_W: 
    1022                 case XC_FETCH_RW: 
    1023                 case XC_FETCH_FUNC_ARG: 
    1024                 case XC_FETCH_UNSET: 
    1025                 case XC_FETCH_IS: 
    1026                 case XC_UNSET_VAR: 
    1027                     $rvalue = $this->getOpVal($op1, $EX); 
    1028                     if (defined('ZEND_FETCH_TYPE_MASK')) { 
    1029                         $fetchtype = ($ext & ZEND_FETCH_TYPE_MASK); 
    1030                     } 
    1031                     else { 
    1032                         $fetchtype = $op2[!ZEND_ENGINE_2 ? 'fetch_type' : 'EA.type']; 
    1033                     } 
    1034                     switch ($fetchtype) { 
    1035                     case ZEND_FETCH_STATIC_MEMBER: 
    1036                         $class = $this->getOpVal($op2, $EX); 
    1037                         $rvalue = str($class) . '::$' . unquoteName($rvalue, $EX); 
    1038                         break; 
    1039                     default: 
    1040                         $name = unquoteName($rvalue, $EX); 
    1041                         $globalname = xcache_is_autoglobal($name) ? "\$$name" : "\$GLOBALS[" . str($rvalue) . "]"; 
    1042                         $rvalue = new Decompiler_Fetch($rvalue, $fetchtype, $globalname); 
    1043                         break; 
    1044                     } 
    1045                     if ($opc == XC_UNSET_VAR) { 
    1046                         $op['php'] = "unset(" . str($rvalue, $EX) . ")"; 
    1047                         $lastphpop = &$op; 
    1048                     } 
    1049                     else if ($res['op_type'] != XC_IS_UNUSED) { 
    1050                         $resvar = $rvalue; 
    1051                     } 
    1052                     break; 
    1053                     // }}} 
    1054                     // {{{ case XC_FETCH_DIM_* 
    1055                 case XC_FETCH_DIM_TMP_VAR: 
    1056                 case XC_FETCH_DIM_R: 
    1057                 case XC_FETCH_DIM_W: 
    1058                 case XC_FETCH_DIM_RW: 
    1059                 case XC_FETCH_DIM_FUNC_ARG: 
    1060                 case XC_FETCH_DIM_UNSET: 
    1061                 case XC_FETCH_DIM_IS: 
    1062                 case XC_ASSIGN_DIM: 
    1063                 case XC_UNSET_DIM_OBJ: // PHP 4 only 
    1064                 case XC_UNSET_DIM: 
    1065                 case XC_UNSET_OBJ: 
    1066                     $src = $this->getOpVal($op1, $EX, false); 
    1067                     if (is_a($src, "Decompiler_ForeachBox")) { 
    1068                         $src->iskey = $this->getOpVal($op2, $EX); 
    1069                         $resvar = $src; 
    1070                         break; 
    1071                     } 
    1072  
    1073                     if (is_a($src, "Decompiler_DimBox")) { 
    1074                         $dimbox = $src; 
    1075                     } 
    1076                     else { 
    1077                         if (!is_a($src, "Decompiler_ListBox")) { 
    1078                             $op1val = $this->getOpVal($op1, $EX, false); 
    1079                             $list = new Decompiler_List(isset($op1val) ? $op1val : '$this'); 
    1080  
    1081                             $src = new Decompiler_ListBox($list); 
    1082                             if (!isset($op1['var'])) { 
    1083                                 $this->dumpop($op, $EX); 
    1084                                 var_dump($op); 
    1085                                 die('missing var'); 
    1086                             } 
    1087                             $T[$op1['var']] = $src; 
    1088                             unset($list); 
    1089                         } 
    1090                         $dim = new Decompiler_Dim($src); 
    1091                         $src->obj->dims[] = &$dim; 
    1092  
    1093                         $dimbox = new Decompiler_DimBox($dim); 
    1094                     } 
    1095                     $dim = &$dimbox->obj; 
    1096                     $dim->offsets[] = $this->getOpVal($op2, $EX); 
    1097                     if ($ext == ZEND_FETCH_ADD_LOCK) { 
    1098                         $src->obj->everLocked = true; 
    1099                     } 
    1100                     else if ($ext == ZEND_FETCH_STANDARD) { 
    1101                         $dim->isLast = true; 
    1102                     } 
    1103                     if ($opc == XC_UNSET_OBJ) { 
    1104                         $dim->isObject = true; 
    1105                     } 
    1106                     unset($dim); 
    1107                     $rvalue = $dimbox; 
    1108                     unset($dimbox); 
    1109  
    1110                     if ($opc == XC_ASSIGN_DIM) { 
    1111                         $lvalue = $rvalue; 
    1112                         ++ $i; 
    1113                         $rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX); 
    1114                         $resvar = str($lvalue, $EX) . ' = ' . str($rvalue); 
    1115                     } 
    1116                     else if ($opc == XC_UNSET_DIM || $opc == XC_UNSET_OBJ) { 
    1117                         $op['php'] = "unset(" . str($rvalue, $EX) . ")"; 
    1118                         $lastphpop = &$op; 
    1119                     } 
    1120                     else if ($res['op_type'] != XC_IS_UNUSED) { 
    1121                         $resvar = $rvalue; 
    1122                     } 
    1123                     break; 
    1124                     // }}} 
    1125                 case XC_ASSIGN: // {{{ 
    1126                     $lvalue = $this->getOpVal($op1, $EX); 
    1127                     $rvalue = $this->getOpVal($op2, $EX, false); 
    1128                     if (is_a($rvalue, 'Decompiler_ForeachBox')) { 
    1129                         $type = $rvalue->iskey ? 'fe_key' : 'fe_as'; 
    1130                         $rvalue->obj[$type] = $lvalue; 
    1131                         unset($T[$op2['var']]); 
    1132                         break; 
    1133                     } 
    1134                     if (is_a($rvalue, "Decompiler_DimBox")) { 
    1135                         $dim = &$rvalue->obj; 
    1136                         $dim->assign = $lvalue; 
    1137                         if ($dim->isLast) { 
    1138                             $resvar = foldToCode($dim->value, $EX); 
    1139                         } 
    1140                         unset($dim); 
    1141                         break; 
    1142                     } 
    1143                     if (is_a($rvalue, 'Decompiler_Fetch')) { 
    1144                         $src = str($rvalue->src, $EX); 
    1145                         if ('$' . unquoteName($src) == $lvalue) { 
    1146                             switch ($rvalue->fetchType) { 
    1147                             case ZEND_FETCH_STATIC: 
    1148                                 $statics = &$EX['op_array']['static_variables']; 
    1149                                 if ((xcache_get_type($statics[$name]) & IS_LEXICAL_VAR)) { 
    1150                                     $EX['uses'][] = str($lvalue); 
    1151                                     unset($statics); 
    1152                                     break 2; 
    1153                                 } 
    1154                                 unset($statics); 
    1155                             } 
    1156                         } 
    1157                     } 
    1158                     $resvar = "$lvalue = " . str($rvalue, $EX); 
    1159                     break; 
    1160                     // }}} 
    1161                 case XC_ASSIGN_REF: // {{{ 
    1162                     $lvalue = $this->getOpVal($op1, $EX); 
    1163                     $rvalue = $this->getOpVal($op2, $EX, false); 
    1164                     if (is_a($rvalue, 'Decompiler_Fetch')) { 
    1165                         $src = str($rvalue->src, $EX); 
    1166                         if ('$' . unquoteName($src) == $lvalue) { 
    1167                             switch ($rvalue->fetchType) { 
    1168                             case ZEND_FETCH_GLOBAL: 
    1169                             case ZEND_FETCH_GLOBAL_LOCK: 
    1170                                 $resvar = 'global ' . $lvalue; 
    1171                                 break 2; 
    1172                             case ZEND_FETCH_STATIC: 
    1173                                 $statics = &$EX['op_array']['static_variables']; 
    1174                                 if ((xcache_get_type($statics[$name]) & IS_LEXICAL_REF)) { 
    1175                                     $EX['uses'][] = '&' . str($lvalue); 
    1176                                     unset($statics); 
    1177                                     break 2; 
    1178                                 } 
    1179  
    1180                                 $resvar = 'static ' . $lvalue; 
    1181                                 $name = unquoteName($src); 
    1182                                 if (isset($statics[$name])) { 
    1183                                     $var = $statics[$name]; 
    1184                                     $resvar .= ' = '; 
    1185                                     $resvar .= str(value($var), $EX); 
    1186                                 } 
     1579                } 
     1580                if (is_a($rvalue, 'Decompiler_Fetch')) { 
     1581                    $src = str($rvalue->src, $EX); 
     1582                    if ('$' . unquoteName($src) == $lvalue) { 
     1583                        switch ($rvalue->fetchType) { 
     1584                        case ZEND_FETCH_STATIC: 
     1585                            $statics = &$EX['op_array']['static_variables']; 
     1586                            if ((xcache_get_type($statics[$name]) & IS_LEXICAL_VAR)) { 
     1587                                $EX['uses'][] = str($lvalue); 
    11871588                                unset($statics); 
    11881589                                break 2; 
    1189                             default: 
    11901590                            } 
     1591                            unset($statics); 
    11911592                        } 
    11921593                    } 
    1193                     // TODO: PHP_6 global 
    1194                     $rvalue = str($rvalue, $EX); 
    1195                     $resvar = "$lvalue = &$rvalue"; 
     1594                } 
     1595                $resvar = new Decompiler_Binop($this, $lvalue, XC_ASSIGN, $rvalue); 
     1596                break; 
     1597                // }}} 
     1598            case XC_ASSIGN_REF: // {{{ 
     1599                $lvalue = $this->getOpVal($op1, $EX); 
     1600                $rvalue = $this->getOpVal($op2, $EX); 
     1601                if (is_a($rvalue, 'Decompiler_Fetch')) { 
     1602                    $src = str($rvalue->src, $EX); 
     1603                    if ('$' . unquoteName($src) == $lvalue) { 
     1604                        switch ($rvalue->fetchType) { 
     1605                        case ZEND_FETCH_GLOBAL: 
     1606                        case ZEND_FETCH_GLOBAL_LOCK: 
     1607                            $resvar = 'global ' . $lvalue; 
     1608                            break 2; 
     1609                        case ZEND_FETCH_STATIC: 
     1610                            $statics = &$EX['op_array']['static_variables']; 
     1611                            if ((xcache_get_type($statics[$name]) & IS_LEXICAL_REF)) { 
     1612                                $EX['uses'][] = '&' . str($lvalue); 
     1613                                unset($statics); 
     1614                                break 2; 
     1615                            } 
     1616 
     1617                            $resvar = 'static ' . $lvalue; 
     1618                            $name = unquoteName($src); 
     1619                            if (isset($statics[$name])) { 
     1620                                $var = $statics[$name]; 
     1621                                $resvar .= ' = '; 
     1622                                $resvar .= str(value($var), $EX); 
     1623                            } 
     1624                            unset($statics); 
     1625                            break 2; 
     1626                        default: 
     1627                        } 
     1628                    } 
     1629                } 
     1630                // TODO: PHP_6 global 
     1631                $resvar = new Decompiler_Binop($this, $lvalue, XC_ASSIGN_REF, $rvalue); 
     1632                break; 
     1633                // }}} 
     1634            // {{{ case XC_FETCH_OBJ_* 
     1635            case XC_FETCH_OBJ_R: 
     1636            case XC_FETCH_OBJ_W: 
     1637            case XC_FETCH_OBJ_RW: 
     1638            case XC_FETCH_OBJ_FUNC_ARG: 
     1639            case XC_FETCH_OBJ_UNSET: 
     1640            case XC_FETCH_OBJ_IS: 
     1641            case XC_ASSIGN_OBJ: 
     1642                $obj = $this->getOpVal($op1, $EX); 
     1643                if (!isset($obj)) { 
     1644                    $obj = '$this'; 
     1645                } 
     1646                $rvalue = str($obj) . "->" . unquoteVariableName($this->getOpVal($op2, $EX), $EX); 
     1647                if ($res['op_type'] != XC_IS_UNUSED) { 
     1648                    $resvar = $rvalue; 
     1649                } 
     1650                if ($opc == XC_ASSIGN_OBJ) { 
     1651                    ++ $i; 
     1652                    $lvalue = $rvalue; 
     1653                    $rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX); 
     1654                    $resvar = "$lvalue = " . str($rvalue); 
     1655                } 
     1656                break; 
     1657                // }}} 
     1658            case XC_ISSET_ISEMPTY_DIM_OBJ: 
     1659            case XC_ISSET_ISEMPTY_PROP_OBJ: 
     1660            case XC_ISSET_ISEMPTY: 
     1661            case XC_ISSET_ISEMPTY_VAR: // {{{ 
     1662                if ($opc == XC_ISSET_ISEMPTY_VAR) { 
     1663                    $rvalue = $this->getOpVal($op1, $EX); 
     1664                    // for < PHP_5_3 
     1665                    if ($op1['op_type'] == XC_IS_CONST) { 
     1666                        $rvalue = '$' . unquoteVariableName($this->getOpVal($op1, $EX)); 
     1667                    } 
     1668                    if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) { 
     1669                        $class = $this->getOpVal($op2, $EX); 
     1670                        $rvalue = $class . '::' . $rvalue; 
     1671                    } 
     1672                } 
     1673                else if ($opc == XC_ISSET_ISEMPTY) { 
     1674                    $rvalue = $this->getOpVal($op1, $EX); 
     1675                } 
     1676                else { 
     1677                    $container = $this->getOpVal($op1, $EX); 
     1678                    $dim = $this->getOpVal($op2, $EX); 
     1679                    if ($opc == XC_ISSET_ISEMPTY_PROP_OBJ) { 
     1680                        if (!isset($container)) { 
     1681                            $container = '$this'; 
     1682                        } 
     1683                        $rvalue = $container . "->" . unquoteVariableName($dim); 
     1684                    } 
     1685                    else { 
     1686                        $rvalue = $container . '[' . str($dim) .']'; 
     1687                    } 
     1688                } 
     1689 
     1690                switch ((!ZEND_ENGINE_2 ? $op['op2']['var'] /* constant */ : $ext) & (ZEND_ISSET|ZEND_ISEMPTY)) { 
     1691                case ZEND_ISSET: 
     1692                    $rvalue = "isset(" . str($rvalue) . ")"; 
    11961693                    break; 
    1197                     // }}} 
    1198                 // {{{ case XC_FETCH_OBJ_* 
    1199                 case XC_FETCH_OBJ_R: 
    1200                 case XC_FETCH_OBJ_W: 
    1201                 case XC_FETCH_OBJ_RW: 
    1202                 case XC_FETCH_OBJ_FUNC_ARG: 
    1203                 case XC_FETCH_OBJ_UNSET: 
    1204                 case XC_FETCH_OBJ_IS: 
    1205                 case XC_ASSIGN_OBJ: 
     1694                case ZEND_ISEMPTY: 
     1695                    $rvalue = "empty(" . str($rvalue) . ")"; 
     1696                    break; 
     1697                } 
     1698                $resvar = $rvalue; 
     1699                break; 
     1700                // }}} 
     1701            case XC_SEND_VAR_NO_REF: 
     1702            case XC_SEND_VAL: 
     1703            case XC_SEND_REF: 
     1704            case XC_SEND_VAR: // {{{ 
     1705                $ref = ($opc == XC_SEND_REF ? '&' : ''); 
     1706                $EX['argstack'][] = $ref . str($this->getOpVal($op1, $EX)); 
     1707                break; 
     1708                // }}} 
     1709            case XC_INIT_STATIC_METHOD_CALL: 
     1710            case XC_INIT_METHOD_CALL: // {{{ 
     1711                array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope'])); 
     1712                if ($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL || $op1['op_type'] != XC_IS_UNUSED) { 
    12061713                    $obj = $this->getOpVal($op1, $EX); 
    12071714                    if (!isset($obj)) { 
    12081715                        $obj = '$this'; 
    12091716                    } 
    1210                     $rvalue = str($obj) . "->" . unquoteVariableName($this->getOpVal($op2, $EX), $EX); 
     1717                    if ($opc == XC_INIT_STATIC_METHOD_CALL || /* PHP4 */ isset($op1['constant'])) { 
     1718                        $EX['object'] = null; 
     1719                        $EX['called_scope'] = $this->stripNamespace(unquoteName($obj, $EX)); 
     1720                    } 
     1721                    else { 
     1722                        $EX['object'] = $obj; 
     1723                        $EX['called_scope'] = null; 
     1724                    } 
    12111725                    if ($res['op_type'] != XC_IS_UNUSED) { 
    1212                         $resvar = $rvalue; 
    1213                     } 
    1214                     if ($opc == XC_ASSIGN_OBJ) { 
    1215                         ++ $i; 
    1216                         $lvalue = $rvalue; 
    1217                         $rvalue = $this->getOpVal($opcodes[$i]['op1'], $EX); 
    1218                         $resvar = "$lvalue = " . str($rvalue); 
    1219                     } 
    1220                     break; 
    1221                     // }}} 
    1222                 case XC_ISSET_ISEMPTY_DIM_OBJ: 
    1223                 case XC_ISSET_ISEMPTY_PROP_OBJ: 
    1224                 case XC_ISSET_ISEMPTY: 
    1225                 case XC_ISSET_ISEMPTY_VAR: // {{{ 
    1226                     if ($opc == XC_ISSET_ISEMPTY_VAR) { 
    1227                         $rvalue = $this->getOpVal($op1, $EX); 
    1228                         // for < PHP_5_3 
    1229                         if ($op1['op_type'] == XC_IS_CONST) { 
    1230                             $rvalue = '$' . unquoteVariableName($this->getOpVal($op1, $EX)); 
    1231                         } 
    1232                         if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) { 
    1233                             $class = $this->getOpVal($op2, $EX); 
    1234                             $rvalue = $class . '::' . $rvalue; 
    1235                         } 
    1236                     } 
    1237                     else if ($opc == XC_ISSET_ISEMPTY) { 
    1238                         $rvalue = $this->getOpVal($op1, $EX); 
    1239                     } 
    1240                     else { 
    1241                         $container = $this->getOpVal($op1, $EX); 
    1242                         $dim = $this->getOpVal($op2, $EX); 
    1243                         if ($opc == XC_ISSET_ISEMPTY_PROP_OBJ) { 
    1244                             if (!isset($container)) { 
    1245                                 $container = '$this'; 
    1246                             } 
    1247                             $rvalue = $container . "->" . unquoteVariableName($dim); 
    1248                         } 
    1249                         else { 
    1250                             $rvalue = $container . '[' . str($dim) .']'; 
    1251                         } 
    1252                     } 
    1253  
    1254                     switch ((!ZEND_ENGINE_2 ? $op['op2']['var'] /* constant */ : $ext) & (ZEND_ISSET|ZEND_ISEMPTY)) { 
    1255                     case ZEND_ISSET: 
    1256                         $rvalue = "isset(" . str($rvalue) . ")"; 
    1257                         break; 
    1258                     case ZEND_ISEMPTY: 
    1259                         $rvalue = "empty(" . str($rvalue) . ")"; 
    1260                         break; 
    1261                     } 
    1262                     $resvar = $rvalue; 
    1263                     break; 
    1264                     // }}} 
    1265                 case XC_SEND_VAR_NO_REF: 
    1266                 case XC_SEND_VAL: 
    1267                 case XC_SEND_REF: 
    1268                 case XC_SEND_VAR: // {{{ 
    1269                     $ref = ($opc == XC_SEND_REF ? '&' : ''); 
    1270                     $EX['argstack'][] = $ref . str($this->getOpVal($op1, $EX)); 
    1271                     break; 
    1272                     // }}} 
    1273                 case XC_INIT_STATIC_METHOD_CALL: 
    1274                 case XC_INIT_METHOD_CALL: // {{{ 
    1275                     array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope'])); 
    1276                     if ($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL || $op1['op_type'] != XC_IS_UNUSED) { 
    1277                         $obj = $this->getOpVal($op1, $EX); 
    1278                         if (!isset($obj)) { 
    1279                             $obj = '$this'; 
    1280                         } 
    1281                         if ($opc == XC_INIT_STATIC_METHOD_CALL || /* PHP4 */ isset($op1['constant'])) { 
    1282                             $EX['object'] = null; 
    1283                             $EX['called_scope'] = $this->stripNamespace(unquoteName($obj, $EX)); 
    1284                         } 
    1285                         else { 
    1286                             $EX['object'] = $obj; 
    1287                             $EX['called_scope'] = null; 
    1288                         } 
    1289                         if ($res['op_type'] != XC_IS_UNUSED) { 
    1290                             $resvar = '$obj call$'; 
    1291                         } 
    1292                     } 
    1293                     else { 
    1294                         $EX['object'] = null; 
    1295                         $EX['called_scope'] = null; 
    1296                     } 
    1297  
    1298                     $EX['fbc'] = $this->getOpVal($op2, $EX, false); 
    1299                     if (($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL) && !isset($EX['fbc'])) { 
    1300                         $EX['fbc'] = '__construct'; 
    1301                     } 
    1302                     break; 
    1303                     // }}} 
    1304                 case XC_INIT_NS_FCALL_BY_NAME: 
    1305                 case XC_INIT_FCALL_BY_NAME: // {{{ 
    1306                     array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope'])); 
    1307                     if (!ZEND_ENGINE_2 && ($ext & ZEND_CTOR_CALL)) { 
    1308                         break; 
    1309                     } 
     1726                        $resvar = '$obj call$'; 
     1727                    } 
     1728                } 
     1729                else { 
    13101730                    $EX['object'] = null; 
    13111731                    $EX['called_scope'] = null; 
    1312                     $EX['fbc'] = $this->getOpVal($op2, $EX); 
     1732                } 
     1733 
     1734                $EX['fbc'] = $this->getOpVal($op2, $EX); 
     1735                if (($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL) && !isset($EX['fbc'])) { 
     1736                    $EX['fbc'] = '__construct'; 
     1737                } 
     1738                break; 
     1739                // }}} 
     1740            case XC_INIT_NS_FCALL_BY_NAME: 
     1741            case XC_INIT_FCALL_BY_NAME: // {{{ 
     1742                array_push($EX['arg_types_stack'], array($EX['fbc'], $EX['object'], $EX['called_scope'])); 
     1743                if (!ZEND_ENGINE_2 && ($ext & ZEND_CTOR_CALL)) { 
    13131744                    break; 
    1314                     // }}} 
    1315                 case XC_INIT_FCALL_BY_FUNC: // {{{ deprecated even in PHP 4? 
    1316                     $EX['object'] = null; 
    1317                     $EX['called_scope'] = null; 
    1318                     $which = $op1['var']; 
    1319                     $EX['fbc'] = $EX['op_array']['funcs'][$which]['name']; 
     1745                } 
     1746                $EX['object'] = null; 
     1747                $EX['called_scope'] = null; 
     1748                $EX['fbc'] = $this->getOpVal($op2, $EX); 
     1749                break; 
     1750                // }}} 
     1751            case XC_INIT_FCALL_BY_FUNC: // {{{ deprecated even in PHP 4? 
     1752                $EX['object'] = null; 
     1753                $EX['called_scope'] = null; 
     1754                $which = $op1['var']; 
     1755                $EX['fbc'] = $EX['op_array']['funcs'][$which]['name']; 
     1756                break; 
     1757                // }}} 
     1758            case XC_DO_FCALL_BY_FUNC: 
     1759                $which = $op1['var']; 
     1760                $fname = $EX['op_array']['funcs'][$which]['name']; 
     1761                $args = $this->popargs($EX, $ext); 
     1762                $resvar = $fname . "($args)"; 
     1763                break; 
     1764            case XC_DO_FCALL: 
     1765                $fname = unquoteName($this->getOpVal($op1, $EX), $EX); 
     1766                $args = $this->popargs($EX, $ext); 
     1767                $resvar = $fname . "($args)"; 
     1768                break; 
     1769            case XC_DO_FCALL_BY_NAME: // {{{ 
     1770                $object = null; 
     1771 
     1772                $fname = unquoteName($EX['fbc'], $EX); 
     1773                if (!is_int($EX['object'])) { 
     1774                    $object = $EX['object']; 
     1775                } 
     1776 
     1777                $args = $this->popargs($EX, $ext); 
     1778 
     1779                $prefix = (isset($object) ? $object . '->' : '' ) 
     1780                    . (isset($EX['called_scope']) ? $EX['called_scope'] . '::' : '' ); 
     1781                $resvar = $prefix 
     1782                    . (!$prefix ? $this->stripNamespace($fname) : $fname) 
     1783                    . "($args)"; 
     1784                unset($args); 
     1785 
     1786                if (is_int($EX['object'])) { 
     1787                    $T[$EX['object']] = $resvar; 
     1788                    $resvar = null; 
     1789                } 
     1790                list($EX['fbc'], $EX['object'], $EX['called_scope']) = array_pop($EX['arg_types_stack']); 
     1791                break; 
     1792                // }}} 
     1793            case XC_VERIFY_ABSTRACT_CLASS: // {{{ 
     1794                //unset($T[$op1['var']]); 
     1795                break; 
     1796                // }}} 
     1797            case XC_DECLARE_CLASS:  
     1798            case XC_DECLARE_INHERITED_CLASS: 
     1799            case XC_DECLARE_INHERITED_CLASS_DELAYED: // {{{ 
     1800                $key = $op1['constant']; 
     1801                if (!isset($this->dc['class_table'][$key])) { 
     1802                    echo 'class not found: ', $key, 'existing classes are:', "\n"; 
     1803                    var_dump(array_keys($this->dc['class_table'])); 
     1804                    exit; 
     1805                } 
     1806                $class = &$this->dc['class_table'][$key]; 
     1807                if (!isset($class['name'])) { 
     1808                    $class['name'] = unquoteName($this->getOpVal($op2, $EX), $EX); 
     1809                } 
     1810                if ($opc == XC_DECLARE_INHERITED_CLASS || $opc == XC_DECLARE_INHERITED_CLASS_DELAYED) { 
     1811                    $ext /= XC_SIZEOF_TEMP_VARIABLE; 
     1812                    $class['parent'] = $T[$ext]; 
     1813                    unset($T[$ext]); 
     1814                } 
     1815                else { 
     1816                    $class['parent'] = null; 
     1817                } 
     1818 
     1819                for (;;) { 
     1820                    if ($i + 1 <= $range[1] 
     1821                     && $opcodes[$i + 1]['opcode'] == XC_ADD_INTERFACE 
     1822                     && $opcodes[$i + 1]['op1']['var'] == $res['var']) { 
     1823                        // continue 
     1824                    } 
     1825                    else if ($i + 2 <= $range[1] 
     1826                     && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE 
     1827                     && $opcodes[$i + 2]['op1']['var'] == $res['var'] 
     1828                     && $opcodes[$i + 1]['opcode'] == XC_FETCH_CLASS) { 
     1829                        // continue 
     1830                    } 
     1831                    else { 
     1832                        break; 
     1833                    } 
     1834                    $this->usedOps[XC_ADD_INTERFACE] = true; 
     1835 
     1836                    $fetchop = &$opcodes[$i + 1]; 
     1837                    $interface = $this->stripNamespace(unquoteName($this->getOpVal($fetchop['op2'], $EX), $EX)); 
     1838                    $addop = &$opcodes[$i + 2]; 
     1839                    $class['interfaces'][$addop['extended_value']] = $interface; 
     1840                    unset($fetchop, $addop); 
     1841                    $i += 2; 
     1842                } 
     1843                $this->dclass($class, $EX['indent']); 
     1844                echo "\n"; 
     1845                unset($class); 
     1846                break; 
     1847                // }}} 
     1848            case XC_INIT_STRING: // {{{ 
     1849                $resvar = "''"; 
     1850                break; 
     1851                // }}} 
     1852            case XC_ADD_CHAR: 
     1853            case XC_ADD_STRING: 
     1854            case XC_ADD_VAR: // {{{ 
     1855                $op1val = $this->getOpVal($op1, $EX); 
     1856                $op2val = $this->getOpVal($op2, $EX); 
     1857                switch ($opc) { 
     1858                case XC_ADD_CHAR: 
     1859                    $op2val = value(chr(str($op2val))); 
    13201860                    break; 
    1321                     // }}} 
    1322                 case XC_DO_FCALL_BY_FUNC: 
    1323                     $which = $op1['var']; 
    1324                     $fname = $EX['op_array']['funcs'][$which]['name']; 
    1325                     $args = $this->popargs($EX, $ext); 
    1326                     $resvar = $fname . "($args)"; 
     1861                case XC_ADD_STRING: 
    13271862                    break; 
    1328                 case XC_DO_FCALL: 
    1329                     $fname = unquoteName($this->getOpVal($op1, $EX, false), $EX); 
    1330                     $args = $this->popargs($EX, $ext); 
    1331                     $resvar = $fname . "($args)"; 
     1863                case XC_ADD_VAR: 
    13321864                    break; 
    1333                 case XC_DO_FCALL_BY_NAME: // {{{ 
    1334                     $object = null; 
    1335  
    1336                     $fname = unquoteName($EX['fbc'], $EX); 
    1337                     if (!is_int($EX['object'])) { 
    1338                         $object = $EX['object']; 
    1339                     } 
    1340  
    1341                     $args = $this->popargs($EX, $ext); 
    1342  
    1343                     $prefix = (isset($object) ? $object . '->' : '' ) 
    1344                         . (isset($EX['called_scope']) ? $EX['called_scope'] . '::' : '' ); 
    1345                     $resvar = $prefix 
    1346                         . (!$prefix ? $this->stripNamespace($fname) : $fname) 
    1347                         . "($args)"; 
    1348                     unset($args); 
    1349  
    1350                     if (is_int($EX['object'])) { 
    1351                         $T[$EX['object']] = $resvar; 
    1352                         $resvar = null; 
    1353                     } 
    1354                     list($EX['fbc'], $EX['object'], $EX['called_scope']) = array_pop($EX['arg_types_stack']); 
    1355                     break; 
    1356                     // }}} 
    1357                 case XC_VERIFY_ABSTRACT_CLASS: // {{{ 
    1358                     //unset($T[$op1['var']]); 
    1359                     break; 
    1360                     // }}} 
    1361                 case XC_DECLARE_CLASS:  
    1362                 case XC_DECLARE_INHERITED_CLASS: 
    1363                 case XC_DECLARE_INHERITED_CLASS_DELAYED: // {{{ 
    1364                     $key = $op1['constant']; 
    1365                     if (!isset($this->dc['class_table'][$key])) { 
    1366                         echo 'class not found: ', $key, 'existing classes are:', "\n"; 
    1367                         var_dump(array_keys($this->dc['class_table'])); 
    1368                         exit; 
    1369                     } 
    1370                     $class = &$this->dc['class_table'][$key]; 
    1371                     if (!isset($class['name'])) { 
    1372                         $class['name'] = unquoteName($this->getOpVal($op2, $EX), $EX); 
    1373                     } 
    1374                     if ($opc == XC_DECLARE_INHERITED_CLASS || $opc == XC_DECLARE_INHERITED_CLASS_DELAYED) { 
    1375                         $ext /= XC_SIZEOF_TEMP_VARIABLE; 
    1376                         $class['parent'] = $T[$ext]; 
    1377                         unset($T[$ext]); 
     1865                } 
     1866                if (str($op1val) == "''") { 
     1867                    $rvalue = $op2val; 
     1868                } 
     1869                else if (str($op2val) == "''") { 
     1870                    $rvalue = $op1val; 
     1871                } 
     1872                else { 
     1873                    $rvalue = str($op1val) . ' . ' . str($op2val); 
     1874                } 
     1875                $resvar = $rvalue; 
     1876                // }}} 
     1877                break; 
     1878            case XC_PRINT: // {{{ 
     1879                $op1val = $this->getOpVal($op1, $EX); 
     1880                $resvar = "print(" . str($op1val) . ")"; 
     1881                break; 
     1882                // }}} 
     1883            case XC_ECHO: // {{{ 
     1884                $op1val = $this->getOpVal($op1, $EX); 
     1885                $resvar = "echo " . str($op1val); 
     1886                break; 
     1887                // }}} 
     1888            case XC_EXIT: // {{{ 
     1889                $op1val = $this->getOpVal($op1, $EX); 
     1890                $resvar = "exit($op1val)"; 
     1891                break; 
     1892                // }}} 
     1893            case XC_INIT_ARRAY: 
     1894            case XC_ADD_ARRAY_ELEMENT: // {{{ 
     1895                $rvalue = $this->getOpVal($op1, $EX, true); 
     1896 
     1897                if ($opc == XC_ADD_ARRAY_ELEMENT) { 
     1898                    $assoc = $this->getOpVal($op2, $EX); 
     1899                    if (isset($assoc)) { 
     1900                        $curResVar->value[] = array($assoc, $rvalue); 
    13781901                    } 
    13791902                    else { 
    1380                         $class['parent'] = null; 
    1381                     } 
    1382  
    1383                     for (;;) { 
    1384                         if ($i + 1 < $ic 
    1385                          && $opcodes[$i + 1]['opcode'] == XC_ADD_INTERFACE 
    1386                          && $opcodes[$i + 1]['op1']['var'] == $res['var']) { 
    1387                             // continue 
     1903                        $curResVar->value[] = array(null, $rvalue); 
     1904                    } 
     1905                } 
     1906                else { 
     1907                    if ($opc == XC_INIT_ARRAY) { 
     1908                        $resvar = new Decompiler_Array(); 
     1909                        if (!isset($rvalue)) { 
     1910                            continue; 
    13881911                        } 
    1389                         else if ($i + 2 < $ic 
    1390                          && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE 
    1391                          && $opcodes[$i + 2]['op1']['var'] == $res['var'] 
    1392                          && $opcodes[$i + 1]['opcode'] == XC_FETCH_CLASS) { 
    1393                             // continue 
    1394                         } 
    1395                         else { 
    1396                             break; 
    1397                         } 
    1398                         $this->usedOps[XC_ADD_INTERFACE] = true; 
    1399  
    1400                         $fetchop = &$opcodes[$i + 1]; 
    1401                         $interface = $this->stripNamespace(unquoteName($this->getOpVal($fetchop['op2'], $EX), $EX)); 
    1402                         $addop = &$opcodes[$i + 2]; 
    1403                         $class['interfaces'][$addop['extended_value']] = $interface; 
    1404                         unset($fetchop, $addop); 
    1405                         $i += 2; 
    1406                     } 
    1407                     $this->dclass($class); 
    1408                     echo "\n"; 
    1409                     unset($class); 
    1410                     break; 
    1411                     // }}} 
    1412                 case XC_INIT_STRING: // {{{ 
    1413                     $resvar = "''"; 
    1414                     break; 
    1415                     // }}} 
    1416                 case XC_ADD_CHAR: 
    1417                 case XC_ADD_STRING: 
    1418                 case XC_ADD_VAR: // {{{ 
     1912                    } 
     1913 
     1914                    $assoc = $this->getOpVal($op2, $EX); 
     1915                    if (isset($assoc)) { 
     1916                        $resvar->value[] = array($assoc, $rvalue); 
     1917                    } 
     1918                    else { 
     1919                        $resvar->value[] = array(null, $rvalue); 
     1920                    } 
     1921                } 
     1922                break; 
     1923                // }}} 
     1924            case XC_QM_ASSIGN: // {{{ 
     1925                if (isset($curResVar) && is_a($curResVar, 'Decompiler_Binop')) { 
     1926                    $curResVar->op2 = $this->getOpVal($op1, $EX); 
     1927                } 
     1928                else { 
     1929                    $resvar = $this->getOpVal($op1, $EX); 
     1930                } 
     1931                break; 
     1932                // }}} 
     1933            case XC_BOOL: // {{{ 
     1934                $resvar = /*'(bool) ' .*/ $this->getOpVal($op1, $EX); 
     1935                break; 
     1936                // }}} 
     1937            case XC_RETURN: // {{{ 
     1938                $resvar = "return " . str($this->getOpVal($op1, $EX)); 
     1939                break; 
     1940                // }}} 
     1941            case XC_INCLUDE_OR_EVAL: // {{{ 
     1942                $type = $op2['var']; // hack 
     1943                $keyword = $this->includeTypes[$type]; 
     1944                $resvar = "$keyword " . str($this->getOpVal($op1, $EX)); 
     1945                break; 
     1946                // }}} 
     1947            case XC_FE_RESET: // {{{ 
     1948                $resvar = $this->getOpVal($op1, $EX); 
     1949                break; 
     1950                // }}} 
     1951            case XC_FE_FETCH: // {{{ 
     1952                $op['fe_src'] = $this->getOpVal($op1, $EX, true); 
     1953                $fe = new Decompiler_ForeachBox($op); 
     1954                $fe->iskey = false; 
     1955                $T[$res['var']] = $fe; 
     1956 
     1957                ++ $i; 
     1958                if (($ext & ZEND_FE_FETCH_WITH_KEY)) { 
     1959                    $fe = new Decompiler_ForeachBox($op); 
     1960                    $fe->iskey = true; 
     1961 
     1962                    $res = $opcodes[$i]['result']; 
     1963                    $T[$res['var']] = $fe; 
     1964                } 
     1965                break; 
     1966                // }}} 
     1967            case XC_SWITCH_FREE: // {{{ 
     1968                break; 
     1969                // }}} 
     1970            case XC_FREE: // {{{ 
     1971                $free = $T[$op1['var']]; 
     1972                if (!is_a($free, 'Decompiler_Array') && !is_a($free, 'Decompiler_Box')) { 
     1973                    $op['php'] = is_object($free) ? $free : $this->unquote($free, '(', ')'); 
     1974                    $lastphpop = &$op; 
     1975                } 
     1976                unset($T[$op1['var']], $free); 
     1977                break; 
     1978                // }}} 
     1979            case XC_JMP_NO_CTOR: 
     1980                break; 
     1981            case XC_JMP_SET: // ?: 
     1982                $resvar = new Decompiler_Binop($this, $this->getOpVal($op1, $EX), XC_JMP_SET, null); 
     1983                break; 
     1984            case XC_JMPZ_EX: // and 
     1985            case XC_JMPNZ_EX: // or 
     1986                $resvar = $this->getOpVal($op1, $EX); 
     1987                break; 
     1988 
     1989            case XC_JMPNZ: // while 
     1990            case XC_JMPZNZ: // for 
     1991            case XC_JMPZ: // {{{ 
     1992                break; 
     1993                // }}} 
     1994            case XC_CONT: 
     1995            case XC_BRK: 
     1996                $resvar = $opc == XC_CONT ? 'continue' : 'break'; 
     1997                $count = str($this->getOpVal($op2, $EX)); 
     1998                if ($count != '1') { 
     1999                    $resvar .= ' ' . $count; 
     2000                } 
     2001                break; 
     2002            case XC_GOTO: 
     2003                $resvar = 'goto label' . $op['op1']['var']; 
     2004                $istmpres = false; 
     2005                break; 
     2006 
     2007            case XC_JMP: // {{{ 
     2008                break; 
     2009                // }}} 
     2010            case XC_CASE: 
     2011                // $switchValue = $this->getOpVal($op1, $EX); 
     2012                $caseValue = $this->getOpVal($op2, $EX); 
     2013                $resvar = $caseValue; 
     2014                break; 
     2015            case XC_RECV_INIT: 
     2016            case XC_RECV: 
     2017                $offset = $this->getOpVal($op1, $EX); 
     2018                $lvalue = $this->getOpVal($op['result'], $EX); 
     2019                if ($opc == XC_RECV_INIT) { 
     2020                    $default = value($op['op2']['constant']); 
     2021                } 
     2022                else { 
     2023                    $default = null; 
     2024                } 
     2025                $EX['recvs'][str($offset)] = array($lvalue, $default); 
     2026                break; 
     2027            case XC_POST_DEC: 
     2028            case XC_POST_INC: 
     2029            case XC_POST_DEC_OBJ: 
     2030            case XC_POST_INC_OBJ: 
     2031            case XC_PRE_DEC: 
     2032            case XC_PRE_INC: 
     2033            case XC_PRE_DEC_OBJ: 
     2034            case XC_PRE_INC_OBJ: // {{{ 
     2035                $flags = array_flip(explode('_', $opname)); 
     2036                if (isset($flags['OBJ'])) { 
     2037                    $resvar = $this->getOpVal($op1, $EX) . '->' . unquoteVariableName($this->getOpVal($op2, $EX), $EX); 
     2038                } 
     2039                else { 
     2040                    $resvar = $this->getOpVal($op1, $EX); 
     2041                } 
     2042                $opstr = isset($flags['DEC']) ? '--' : '++'; 
     2043                if (isset($flags['POST'])) { 
     2044                    $resvar .= $opstr; 
     2045                } 
     2046                else { 
     2047                    $resvar = "$opstr$resvar"; 
     2048                } 
     2049                break; 
     2050                // }}} 
     2051 
     2052            case XC_BEGIN_SILENCE: // {{{ 
     2053                $EX['silence'] ++; 
     2054                break; 
     2055                // }}} 
     2056            case XC_END_SILENCE: // {{{ 
     2057                $EX['silence'] --; 
     2058                $lastresvar = '@' . str($lastresvar, $EX); 
     2059                break; 
     2060                // }}} 
     2061            case XC_CAST: // {{{ 
     2062                $type = $ext; 
     2063                static $type2cast = array( 
     2064                        IS_LONG   => '(int)', 
     2065                        IS_DOUBLE => '(double)', 
     2066                        IS_STRING => '(string)', 
     2067                        IS_ARRAY  => '(array)', 
     2068                        IS_OBJECT => '(object)', 
     2069                        IS_BOOL   => '(bool)', 
     2070                        IS_NULL   => '(unset)', 
     2071                        ); 
     2072                assert(isset($type2cast[$type])); 
     2073                $cast = $type2cast[$type]; 
     2074                $resvar = $cast . ' ' . $this->getOpVal($op1, $EX); 
     2075                break; 
     2076                // }}} 
     2077            case XC_EXT_STMT: 
     2078            case XC_EXT_FCALL_BEGIN: 
     2079            case XC_EXT_FCALL_END: 
     2080            case XC_EXT_NOP: 
     2081                break; 
     2082            case XC_DECLARE_FUNCTION: 
     2083                $this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']); 
     2084                break; 
     2085            case XC_DECLARE_LAMBDA_FUNCTION: // {{{ 
     2086                ob_start(); 
     2087                $this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']); 
     2088                $resvar = ob_get_clean(); 
     2089                $istmpres = true; 
     2090                break; 
     2091                // }}} 
     2092            case XC_DECLARE_CONST: 
     2093                $name = $this->stripNamespace(unquoteName($this->getOpVal($op1, $EX), $EX)); 
     2094                $value = str($this->getOpVal($op2, $EX)); 
     2095                $resvar = 'const ' . $name . ' = ' . $value; 
     2096                break; 
     2097            case XC_DECLARE_FUNCTION_OR_CLASS: 
     2098                /* always removed by compiler */ 
     2099                break; 
     2100            case XC_TICKS: 
     2101                $lastphpop['ticks'] = $this->getOpVal($op1, $EX); 
     2102                // $EX['tickschanged'] = true; 
     2103                break; 
     2104            case XC_RAISE_ABSTRACT_ERROR: 
     2105                // abstract function body is empty, don't need this code 
     2106                break; 
     2107            case XC_USER_OPCODE: 
     2108                echo '// ZEND_USER_OPCODE, impossible to decompile'; 
     2109                break; 
     2110            case XC_OP_DATA: 
     2111                break; 
     2112            default: // {{{ 
     2113                $call = array(&$this, $opname); 
     2114                if (is_callable($call)) { 
     2115                    $this->usedOps[$opc] = true; 
     2116                    $this->{$opname}($op, $EX); 
     2117                } 
     2118                else if (isset($this->binops[$opc])) { // {{{ 
     2119                    $this->usedOps[$opc] = true; 
    14192120                    $op1val = $this->getOpVal($op1, $EX); 
    14202121                    $op2val = $this->getOpVal($op2, $EX); 
    1421                     switch ($opc) { 
    1422                     case XC_ADD_CHAR: 
    1423                         $op2val = value(chr(str($op2val))); 
    1424                         break; 
    1425                     case XC_ADD_STRING: 
    1426                         break; 
    1427                     case XC_ADD_VAR: 
    1428                         break; 
    1429                     } 
    1430                     if (str($op1val) == "''") { 
    1431                         $rvalue = $op2val; 
    1432                     } 
    1433                     else if (str($op2val) == "''") { 
    1434                         $rvalue = $op1val; 
    1435                     } 
    1436                     else { 
    1437                         $rvalue = str($op1val) . ' . ' . str($op2val); 
    1438                     } 
     2122                    $rvalue = new Decompiler_Binop($this, $op1val, $opc, $op2val); 
    14392123                    $resvar = $rvalue; 
    14402124                    // }}} 
    1441                     break; 
    1442                 case XC_PRINT: // {{{ 
     2125                } 
     2126                else if (isset($this->unaryops[$opc])) { // {{{ 
     2127                    $this->usedOps[$opc] = true; 
    14432128                    $op1val = $this->getOpVal($op1, $EX); 
    1444                     $resvar = "print(" . str($op1val) . ")"; 
    1445                     break; 
     2129                    $myop = $this->unaryops[$opc]; 
     2130                    $rvalue = $myop . str($op1val); 
     2131                    $resvar = $rvalue; 
    14462132                    // }}} 
    1447                 case XC_ECHO: // {{{ 
    1448                     $op1val = $this->getOpVal($op1, $EX); 
    1449                     $resvar = "echo " . str($op1val); 
    1450                     break; 
    1451                     // }}} 
    1452                 case XC_EXIT: // {{{ 
    1453                     $op1val = $this->getOpVal($op1, $EX); 
    1454                     $resvar = "exit($op1val)"; 
    1455                     break; 
    1456                     // }}} 
    1457                 case XC_INIT_ARRAY: 
    1458                 case XC_ADD_ARRAY_ELEMENT: // {{{ 
    1459                     $rvalue = $this->getOpVal($op1, $EX, false, true); 
    1460  
    1461                     if ($opc == XC_ADD_ARRAY_ELEMENT) { 
    1462                         $assoc = $this->getOpVal($op2, $EX); 
    1463                         if (isset($assoc)) { 
    1464                             $T[$res['var']]->value[] = array($assoc, $rvalue); 
    1465                         } 
    1466                         else { 
    1467                             $T[$res['var']]->value[] = array(null, $rvalue); 
    1468                         } 
    1469                     } 
    1470                     else { 
    1471                         if ($opc == XC_INIT_ARRAY) { 
    1472                             $resvar = new Decompiler_Array(); 
    1473                             if (!isset($rvalue)) { 
    1474                                 continue; 
    1475                             } 
    1476                         } 
    1477  
    1478                         $assoc = $this->getOpVal($op2, $EX); 
    1479                         if (isset($assoc)) { 
    1480                             $resvar->value[] = array($assoc, $rvalue); 
    1481                         } 
    1482                         else { 
    1483                             $resvar->value[] = array(null, $rvalue); 
    1484                         } 
    1485                     } 
    1486                     break; 
    1487                     // }}} 
    1488                 case XC_QM_ASSIGN: // {{{ 
    1489                     $resvar = $this->getOpVal($op1, $EX); 
    1490                     break; 
    1491                     // }}} 
    1492                 case XC_BOOL: // {{{ 
    1493                     $resvar = /*'(bool) ' .*/ $this->getOpVal($op1, $EX); 
    1494                     break; 
    1495                     // }}} 
    1496                 case XC_RETURN: // {{{ 
    1497                     $resvar = "return " . str($this->getOpVal($op1, $EX)); 
    1498                     break; 
    1499                     // }}} 
    1500                 case XC_INCLUDE_OR_EVAL: // {{{ 
    1501                     $type = $op2['var']; // hack 
    1502                     $keyword = $this->includeTypes[$type]; 
    1503                     $resvar = "$keyword " . str($this->getOpVal($op1, $EX)); 
    1504                     break; 
    1505                     // }}} 
    1506                 case XC_FE_RESET: // {{{ 
    1507                     $resvar = $this->getOpVal($op1, $EX); 
    1508                     break; 
    1509                     // }}} 
    1510                 case XC_FE_FETCH: // {{{ 
    1511                     $op['fe_src'] = $this->getOpVal($op1, $EX); 
    1512                     $fe = new Decompiler_ForeachBox($op); 
    1513                     $fe->iskey = false; 
    1514                     $T[$res['var']] = $fe; 
    1515  
    1516                     ++ $i; 
    1517                     if (($ext & ZEND_FE_FETCH_WITH_KEY)) { 
    1518                         $fe = new Decompiler_ForeachBox($op); 
    1519                         $fe->iskey = true; 
    1520  
    1521                         $res = $opcodes[$i]['result']; 
    1522                         $T[$res['var']] = $fe; 
    1523                     } 
    1524                     break; 
    1525                     // }}} 
    1526                 case XC_SWITCH_FREE: // {{{ 
    1527                     // unset($T[$op1['var']]); 
    1528                     break; 
    1529                     // }}} 
    1530                 case XC_FREE: // {{{ 
    1531                     $free = $T[$op1['var']]; 
    1532                     if (!is_a($free, 'Decompiler_Array') && !is_a($free, 'Decompiler_Box')) { 
    1533                         $op['php'] = is_object($free) ? $free : $this->unquote($free, '(', ')'); 
    1534                         $lastphpop = &$op; 
    1535                     } 
    1536                     unset($T[$op1['var']], $free); 
    1537                     break; 
    1538                     // }}} 
    1539                 case XC_JMP_NO_CTOR: 
    1540                     break; 
    1541                 case XC_JMP_SET: // ?: 
    1542                     $resvar = $this->getOpVal($op1, $EX); 
    1543                     $op['cond'] = $resvar;  
    1544                     $op['isjmp'] = true; 
    1545                     break; 
    1546                 case XC_JMPNZ: // while 
    1547                 case XC_JMPZNZ: // for 
    1548                 case XC_JMPZ_EX: // and 
    1549                 case XC_JMPNZ_EX: // or 
    1550                 case XC_JMPZ: // {{{ 
    1551                     if ($opc == XC_JMP_NO_CTOR && $EX['object']) { 
    1552                         $rvalue = $EX['object']; 
    1553                     } 
    1554                     else { 
    1555                         $rvalue = $this->getOpVal($op1, $EX); 
    1556                     } 
    1557  
    1558                     if (isset($op['cond_true'])) { 
    1559                         // any true comes here, so it's a "or" 
    1560                         $rvalue = implode(' or ', $op['cond_true']) . ' or ' . $rvalue; 
    1561                         unset($op['cond_true']); 
    1562                     } 
    1563                     if (isset($op['cond_false'])) { 
    1564                         echo "TODO(cond_false):\n"; 
    1565                         var_dump($op);// exit; 
    1566                     } 
    1567                     if ($opc == XC_JMPZ_EX || $opc == XC_JMPNZ_EX) { 
    1568                         $targetop = &$EX['opcodes'][$op2['opline_num']]; 
    1569                         if ($opc == XC_JMPNZ_EX) { 
    1570                             $targetop['cond_true'][] = foldToCode($rvalue, $EX); 
    1571                         } 
    1572                         else { 
    1573                             $targetop['cond_false'][] = foldToCode($rvalue, $EX); 
    1574                         } 
    1575                         unset($targetop); 
    1576                     } 
    1577                     else { 
    1578                         $op['cond'] = $rvalue;  
    1579                         $op['isjmp'] = true; 
    1580                     } 
    1581                     break; 
    1582                     // }}} 
    1583                 case XC_CONT: 
    1584                 case XC_BRK: 
    1585                     $op['cond'] = null; 
    1586                     $op['isjmp'] = true; 
    1587                     $resvar = $opc == XC_CONT ? 'continue' : 'break'; 
    1588                     $count = str($this->getOpVal($op2, $EX)); 
    1589                     if ($count != '1') { 
    1590                         $resvar .= ' ' . $count; 
    1591                     } 
    1592                     break; 
    1593                 case XC_GOTO: 
    1594                 case XC_JMP: // {{{ 
    1595                     $op['cond'] = null; 
    1596                     $op['isjmp'] = true; 
    1597                     break; 
    1598                     // }}} 
    1599                 case XC_CASE: 
    1600                     $switchValue = $this->getOpVal($op1, $EX); 
    1601                     $caseValue = $this->getOpVal($op2, $EX); 
    1602                     $resvar = str($switchValue) . ' == ' . str($caseValue); 
    1603                     break; 
    1604                 case XC_RECV_INIT: 
    1605                 case XC_RECV: 
    1606                     $offset = $this->getOpVal($op1, $EX); 
    1607                     $lvalue = $this->getOpVal($op['result'], $EX); 
    1608                     if ($opc == XC_RECV_INIT) { 
    1609                         $default = value($op['op2']['constant']); 
    1610                     } 
    1611                     else { 
    1612                         $default = null; 
    1613                     } 
    1614                     $EX['recvs'][str($offset)] = array($lvalue, $default); 
    1615                     break; 
    1616                 case XC_POST_DEC: 
    1617                 case XC_POST_INC: 
    1618                 case XC_POST_DEC_OBJ: 
    1619                 case XC_POST_INC_OBJ: 
    1620                 case XC_PRE_DEC: 
    1621                 case XC_PRE_INC: 
    1622                 case XC_PRE_DEC_OBJ: 
    1623                 case XC_PRE_INC_OBJ: // {{{ 
    1624                     $flags = array_flip(explode('_', $opname)); 
    1625                     if (isset($flags['OBJ'])) { 
    1626                         $resvar = $this->getOpVal($op1, $EX) . '->' . unquoteVariableName($this->getOpVal($op2, $EX), $EX); 
    1627                     } 
    1628                     else { 
    1629                         $resvar = $this->getOpVal($op1, $EX); 
    1630                     } 
    1631                     $opstr = isset($flags['DEC']) ? '--' : '++'; 
    1632                     if (isset($flags['POST'])) { 
    1633                         $resvar .= $opstr; 
    1634                     } 
    1635                     else { 
    1636                         $resvar = "$opstr$resvar"; 
    1637                     } 
    1638                     break; 
    1639                     // }}} 
    1640  
    1641                 case XC_BEGIN_SILENCE: // {{{ 
    1642                     $EX['silence'] ++; 
    1643                     break; 
    1644                     // }}} 
    1645                 case XC_END_SILENCE: // {{{ 
    1646                     $EX['silence'] --; 
    1647                     $lastresvar = '@' . str($lastresvar, $EX); 
    1648                     break; 
    1649                     // }}} 
    1650                 case XC_CAST: // {{{ 
    1651                     $type = $ext; 
    1652                     static $type2cast = array( 
    1653                             IS_LONG   => '(int)', 
    1654                             IS_DOUBLE => '(double)', 
    1655                             IS_STRING => '(string)', 
    1656                             IS_ARRAY  => '(array)', 
    1657                             IS_OBJECT => '(object)', 
    1658                             IS_BOOL   => '(bool)', 
    1659                             IS_NULL   => '(unset)', 
    1660                             ); 
    1661                     assert(isset($type2cast[$type])); 
    1662                     $cast = $type2cast[$type]; 
    1663                     $resvar = $cast . ' ' . $this->getOpVal($op1, $EX); 
    1664                     break; 
    1665                     // }}} 
    1666                 case XC_EXT_STMT: 
    1667                 case XC_EXT_FCALL_BEGIN: 
    1668                 case XC_EXT_FCALL_END: 
    1669                 case XC_EXT_NOP: 
    1670                     break; 
    1671                 case XC_DECLARE_FUNCTION: 
    1672                     $this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']); 
    1673                     break; 
    1674                 case XC_DECLARE_LAMBDA_FUNCTION: // {{{ 
    1675                     ob_start(); 
    1676                     $this->dfunction($this->dc['function_table'][$op1['constant']], $EX['indent']); 
    1677                     $resvar = ob_get_clean(); 
    1678                     $istmpres = true; 
    1679                     break; 
    1680                     // }}} 
    1681                 case XC_DECLARE_CONST: 
    1682                     $name = $this->stripNamespace(unquoteName($this->getOpVal($op1, $EX), $EX)); 
    1683                     $value = str($this->getOpVal($op2, $EX)); 
    1684                     $resvar = 'const ' . $name . ' = ' . $value; 
    1685                     break; 
    1686                 case XC_DECLARE_FUNCTION_OR_CLASS: 
    1687                     /* always removed by compiler */ 
    1688                     break; 
    1689                 case XC_TICKS: 
    1690                     $lastphpop['ticks'] = $this->getOpVal($op1, $EX); 
    1691                     // $EX['tickschanged'] = true; 
    1692                     break; 
    1693                 case XC_RAISE_ABSTRACT_ERROR: 
    1694                     // abstract function body is empty, don't need this code 
    1695                     break; 
    1696                 case XC_USER_OPCODE: 
    1697                     echo '// ZEND_USER_OPCODE, impossible to decompile'; 
    1698                     break; 
    1699                 case XC_OP_DATA: 
    1700                     break; 
    1701                 default: // {{{ 
    1702                     echo "\x1B[31m * TODO ", $opname, "\x1B[0m\n"; 
    1703                     $covered = false; 
    1704                     // }}} 
    1705                 } 
    1706                 if ($covered) { 
    1707                     $this->usedOps[$opc] = true; 
    1708                 } 
    1709             } 
     2133                } 
     2134                else { 
     2135                    $notHandled = true; 
     2136                } 
     2137                // }}} 
     2138            } 
     2139            if ($notHandled) { 
     2140                echo "\x1B[31m * TODO ", $opname, "\x1B[0m\n"; 
     2141            } 
     2142            else { 
     2143                $this->usedOps[$opc] = true; 
     2144            } 
     2145 
    17102146            if (isset($resvar)) { 
    17112147                if ($istmpres) { 
     
    17502186    function dumpop($op, &$EX) // {{{ 
    17512187    { 
     2188        assert('isset($op)'); 
    17522189        $op1 = $op['op1']; 
    17532190        $op2 = $op['op2']; 
     
    17812218                if ($k == 'result') { 
    17822219                    var_dump($op); 
     2220                    assert(0); 
    17832221                    exit; 
    1784                     assert(0); 
    17852222                } 
    17862223                else { 
     
    17902227        } 
    17912228        $d[';'] = $op['extended_value']; 
     2229        if (!empty($op['jmpouts'])) { 
     2230            $d['>>'] = implode(',', $op['jmpouts']); 
     2231        } 
     2232        if (!empty($op['jmpins'])) { 
     2233            $d['<<'] = implode(',', $op['jmpins']); 
     2234        } 
    17922235 
    17932236        foreach ($d as $k => $v) { 
     
    17972240    } 
    17982241    // }}} 
    1799     function dargs(&$EX, $indent) // {{{ 
     2242    function dumpRange(&$EX, $range) // {{{ 
     2243    { 
     2244        for ($i = $range[0]; $i <= $range[1]; ++$i) { 
     2245            echo $EX['indent'], $i, "\t"; $this->dumpop($EX['opcodes'][$i], $EX); 
     2246        } 
     2247        echo $EX['indent'], "==", PHP_EOL; 
     2248    } 
     2249    // }}} 
     2250    function dargs(&$EX) // {{{ 
    18002251    { 
    18012252        $op_array = &$EX['op_array']; 
     
    18572308                    } 
    18582309                } 
    1859                 echo str($arg[0], $indent); 
     2310                echo str($arg[0], $EX); 
    18602311            } 
    18612312            if (isset($arg[1])) { 
    1862                 echo ' = ', str($arg[1], $indent); 
    1863             } 
    1864         } 
    1865     } 
    1866     // }}} 
    1867     function duses(&$EX, $indent) // {{{ 
     2313                echo ' = ', str($arg[1], $EX); 
     2314            } 
     2315        } 
     2316    } 
     2317    // }}} 
     2318    function duses(&$EX) // {{{ 
    18682319    { 
    18692320        if ($EX['uses']) { 
     
    18722323    } 
    18732324    // }}} 
    1874     function dfunction($func, $indent = '', $nobody = false) // {{{ 
     2325    function dfunction($func, $indent = '', $decorations = array(), $nobody = false) // {{{ 
    18752326    { 
    18762327        $this->detectNamespace($func['op_array']['function_name']); 
     
    18842335        else { 
    18852336            ob_start(); 
    1886             $newindent = INDENT . $indent; 
    1887             $EX = &$this->dop_array($func['op_array'], $newindent); 
     2337            $EX = &$this->dop_array($func['op_array'], $indent . INDENT); 
    18882338            $body = ob_get_clean(); 
    18892339        } 
    18902340 
    18912341        $functionName = $this->stripNamespace($func['op_array']['function_name']); 
     2342        $isExpression = false; 
    18922343        if ($functionName == '{closure}') { 
    18932344            $functionName = ''; 
     2345            $isExpression = true; 
     2346        } 
     2347        echo $isExpression ? '' : $indent; 
     2348        if ($decorations) { 
     2349            echo implode(' ', $decorations), ' '; 
    18942350        } 
    18952351        echo 'function', $functionName ? ' ' . $functionName : '', '('; 
    1896         $this->dargs($EX, $indent); 
     2352        $this->dargs($EX); 
    18972353        echo ")"; 
    1898         $this->duses($EX, $indent); 
     2354        $this->duses($EX); 
    18992355        if ($nobody) { 
    19002356            echo ";\n"; 
    19012357        } 
    19022358        else { 
    1903             if ($functionName !== '') { 
     2359            if (!$isExpression) { 
    19042360                echo "\n"; 
    19052361                echo $indent, "{\n"; 
     
    19112367            echo $body; 
    19122368            echo "$indent}"; 
    1913             if ($functionName !== '') { 
     2369            if (!$isExpression) { 
    19142370                echo "\n"; 
    19152371            } 
     
    19272383            echo "\n"; 
    19282384        } 
    1929         $isinterface = false; 
     2385        $isInterface = false; 
     2386        $decorations = array(); 
    19302387        if (!empty($class['ce_flags'])) { 
    19312388            if ($class['ce_flags'] & ZEND_ACC_INTERFACE) { 
    1932                 $isinterface = true; 
     2389                $isInterface = true; 
    19332390            } 
    19342391            else { 
    19352392                if ($class['ce_flags'] & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) { 
    1936                     echo "abstract "; 
     2393                    $decorations[] = "abstract"; 
    19372394                } 
    19382395                if ($class['ce_flags'] & ZEND_ACC_FINAL_CLASS) { 
    1939                     echo "final "; 
    1940                 } 
    1941             } 
    1942         } 
    1943         echo $isinterface ? 'interface ' : 'class ', $this->stripNamespace($class['name']); 
     2396                    $decorations[] = "final"; 
     2397                } 
     2398            } 
     2399        } 
     2400 
     2401        echo $indent; 
     2402        if ($decorations) { 
     2403            echo implode(' ', $decorations), ' '; 
     2404        } 
     2405        echo $isInterface ? 'interface ' : 'class ', $this->stripNamespace($class['name']); 
    19442406        if ($class['parent']) { 
    19452407            echo ' extends ', $class['parent']; 
     
    20552517                        echo "\n"; 
    20562518                    } 
    2057                     echo $newindent; 
    20582519                    $isAbstractMethod = false; 
     2520                    $decorations = array(); 
    20592521                    if (isset($opa['fn_flags'])) { 
    2060                         if (($opa['fn_flags'] & ZEND_ACC_ABSTRACT) && !$isinterface) { 
    2061                             echo "abstract "; 
     2522                        if (($opa['fn_flags'] & ZEND_ACC_ABSTRACT) && !$isInterface) { 
     2523                            $decorations[] = "abstract"; 
    20622524                            $isAbstractMethod = true; 
    20632525                        } 
    20642526                        if ($opa['fn_flags'] & ZEND_ACC_FINAL) { 
    2065                             echo "final "; 
     2527                            $decorations[] = "final"; 
    20662528                        } 
    20672529                        if ($opa['fn_flags'] & ZEND_ACC_STATIC) { 
    2068                             echo "static "; 
     2530                            $decorations[] = "static"; 
    20692531                        } 
    20702532 
    20712533                        switch ($opa['fn_flags'] & ZEND_ACC_PPP_MASK) { 
    20722534                            case ZEND_ACC_PUBLIC: 
    2073                                 echo "public "; 
     2535                                $decorations[] = "public"; 
    20742536                                break; 
    20752537                            case ZEND_ACC_PRIVATE: 
    2076                                 echo "private "; 
     2538                                $decorations[] = "private"; 
    20772539                                break; 
    20782540                            case ZEND_ACC_PROTECTED: 
    2079                                 echo "protected "; 
     2541                                $decorations[] = "protected"; 
    20802542                                break; 
    20812543                            default: 
    2082                                 echo "<visibility error> "; 
     2544                                $decorations[] = "<visibility error>"; 
    20832545                                break; 
    20842546                        } 
    20852547                    } 
    2086                     $this->dfunction($func, $newindent, $isinterface || $isAbstractMethod); 
     2548                    $this->dfunction($func, $newindent, $decorations, $isInterface || $isAbstractMethod); 
    20872549                    if ($opa['function_name'] == 'Decompiler') { 
    20882550                        //exit; 
Note: See TracChangeset for help on using the changeset viewer.