Changeset 799 in svn for trunk


Ignore:
Timestamp:
2011-04-26T08:50:28Z (4 years ago)
Author:
Xuefer
Message:

Decompiler: ?: and ? :

Location:
trunk
Files:
2 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
  • trunk/decompilesample.php

    r797 r799  
    405405$this::__construct();
    406406$obj::__construct();
    407 
    408407$a = $b ?: $d;
    409408$a = ($b ?: $d) + $c;
    410409$a = f1() ?: f2();
     410$a = $b ? $c : $d;
     411$a = ($b ? $c : $d) + $c;
     412$a = f1() ? f3() : f2();
    411413
    412414if ($b ?: $d) {
Note: See TracChangeset for help on using the changeset viewer.