Ignore:
Timestamp:
2011-04-26T10:50:28+02:00 (4 years ago)
Author:
moo
Message:

Decompiler: ?: and ? :

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r796 r799  
    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 . ' ' . 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_JMP_SET             => "?:", 
    488521                ); 
    489522        // }}} 
     
    707740        $lastOp = &$opcodes[$last]; 
    708741 
     742        // {{{ ?: excludign JMP_SET 
     743        if ($firstOp['opcode'] == XC_JMPZ && !empty($firstOp['jmpouts']) 
     744         && $last >= $first + 3 
     745         && $opcodes[$firstOp['jmpouts'][0] - 2]['opcode'] == XC_QM_ASSIGN 
     746         && $opcodes[$firstOp['jmpouts'][0] - 1]['opcode'] == XC_JMP && $opcodes[$firstOp['jmpouts'][0] - 1]['jmpouts'][0] == $last + 1 
     747         && $lastOp['opcode'] == XC_QM_ASSIGN 
     748        ) { 
     749            $trueFirst = $first + 1; 
     750            $trueLast = $firstOp['jmpouts'][0] - 2; 
     751            $falseFirst = $firstOp['jmpouts'][0]; 
     752            $falseLast = $last; 
     753            $this->removeJmpInfo($EX, $first); 
     754 
     755            $condition = $this->getOpVal($firstOp['op1'], $EX); 
     756            $this->recognizeAndDecompileClosedBlocks($EX, $trueFirst, $trueLast, $indent . INDENT); 
     757            $trueValue = $this->getOpVal($opcodes[$trueLast]['op1'], $EX, false, true); 
     758            $this->recognizeAndDecompileClosedBlocks($EX, $falseFirst, $falseLast, $indent . INDENT); 
     759            $falseValue = $this->getOpVal($opcodes[$falseLast]['op1'], $EX, false, true); 
     760            $T[$opcodes[$trueLast]['result']['var']] = new Decompiler_TriOp($condition, $trueValue, $falseValue); 
     761            return false; 
     762        } 
     763        // }}} 
    709764        // {{{ try/catch 
    710765        if (!empty($firstOp['jmpins']) && !empty($opcodes[$firstOp['jmpins'][0]]['isCatchBegin'])) { 
     
    9741029                        $this->decompileBasicBlock($EX, $starti, $blockFirst - 1, $indent); 
    9751030                    } 
    976                     $this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent); 
     1031                    if ($this->decompileComplexBlock($EX, $blockFirst, $blockLast, $indent) === false) { 
     1032                        if ($EX['lastBlock'] == 'complex') { 
     1033                            echo PHP_EOL; 
     1034                        } 
     1035                        $EX['lastBlock'] = null; 
     1036                    } 
    9771037                    $starti = $blockLast + 1; 
    9781038                    $i = $starti; 
     
    10301090            case XC_JMPZ_EX: 
    10311091            case XC_JMPNZ_EX: 
    1032             case XC_JMP_SET: 
     1092            // case XC_JMP_SET: 
    10331093            // case XC_FE_RESET: 
    10341094            case XC_FE_FETCH: 
     
    11111171        $EX['recvs'] = array(); 
    11121172        $EX['uses'] = array(); 
     1173        $EX['lastBlock'] = null; 
    11131174 
    11141175        $first = 0; 
     
    12741335 
    12751336            $resvar = null; 
     1337            unset($curResVar); 
     1338            if (array_key_exists($res['var'], $T)) { 
     1339                $curResVar = &$T[$res['var']]; 
     1340            } 
    12761341            if ((ZEND_ENGINE_2_4 ? ($res['op_type'] & EXT_TYPE_UNUSED) : ($res['EA.type'] & EXT_TYPE_UNUSED)) || $res['op_type'] == XC_IS_UNUSED) { 
    12771342                $istmpres = false; 
     
    18171882                        $assoc = $this->getOpVal($op2, $EX); 
    18181883                        if (isset($assoc)) { 
    1819                             $T[$res['var']]->value[] = array($assoc, $rvalue); 
     1884                            $curResVar->value[] = array($assoc, $rvalue); 
    18201885                        } 
    18211886                        else { 
    1822                             $T[$res['var']]->value[] = array(null, $rvalue); 
     1887                            $curResVar->value[] = array(null, $rvalue); 
    18231888                        } 
    18241889                    } 
     
    18421907                    // }}} 
    18431908                case XC_QM_ASSIGN: // {{{ 
    1844                     $resvar = $this->getOpVal($op1, $EX); 
     1909                    if (isset($curResVar) && is_a($curResVar, 'Decompiler_Binop')) { 
     1910                        $curResVar->op2 = $this->getOpVal($op1, $EX); 
     1911                    } 
     1912                    else { 
     1913                        $resvar = $this->getOpVal($op1, $EX); 
     1914                    } 
    18451915                    break; 
    18461916                    // }}} 
     
    18941964                    break; 
    18951965                case XC_JMP_SET: // ?: 
    1896                     $resvar = $this->getOpVal($op1, $EX); 
    1897                     $op['cond'] = $resvar;  
    1898                     $op['isjmp'] = true; 
     1966                    $resvar = new Decompiler_Binop($this, $this->getOpVal($op1, $EX), XC_JMP_SET, null); 
    18991967                    break; 
    19001968                case XC_JMPNZ: // while 
Note: See TracChangeset for help on using the changeset viewer.