Changeset 716 in svn for trunk/Decompiler.class.php


Ignore:
Timestamp:
2011-04-09T07:07:48Z (4 years ago)
Author:
Xuefer
Message:

PHP 6: initial catch up with php 6 literals and trait

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r714 r716  
    2828
    2929    if (is_array($src)) {
    30         die_error('array str');
     30        exit('array str');
    3131        $src = new Decompiler_Array($src, $indent);
    3232        return $src->__toString();
     
    3636        if (!method_exists($src, '__toString')) {
    3737            var_dump($src);
    38             die_error('no __toString');
     38            exit('no __toString');
    3939        }
    4040        return $src->__toString();
     
    426426        switch ($op['op_type']) {
    427427        case XC_IS_CONST:
    428             return str(value($op['u.constant']));
     428            return str(value($op['constant']));
    429429
    430430        case XC_IS_VAR:
    431431        case XC_IS_TMP_VAR:
    432432            $T = &$EX['Ts'];
    433             $ret = $T[$op['u.var']];
     433            $ret = $T[$op['var']];
    434434            if ($tostr) {
    435435                $ret = str($ret, $EX);
    436436            }
    437437            if ($free) {
    438                 unset($T[$op['u.var']]);
     438                unset($T[$op['var']]);
    439439            }
    440440            return $ret;
    441441
    442442        case XC_IS_CV:
    443             $var = $op['u.var'];
     443            $var = $op['var'];
    444444            $var = $EX['op_array']['vars'][$var];
    445445            return '$' . $var['name'];
     
    448448            return null;
    449449        }
     450    }
     451    // }}}
     452    function removeKeyPrefix($array, $prefix) // {{{
     453    {
     454        $prefixLen = strlen($prefix);
     455        $ret = array();
     456        foreach ($array as $key => $value) {
     457            if (substr($key, 0, $prefixLen) == $prefix) {
     458                $key = substr($key, $prefixLen);
     459            }
     460            $ret[$key] = $value;
     461        }
     462        return $ret;
    450463    }
    451464    // }}}
     
    458471        }
    459472        $EX['indent'] = '';
    460         //for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) {
    461         //  $opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i);
    462         //}
     473        for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) {
     474            if (function_exists('xcache_get_fixed_opcode')) {
     475                $opcodes[$i]['opcode'] = xcache_get_fixed_opcode($opcodes[$i]['opcode'], $i);
     476            }
     477            if (isset($opcodes[$i]['op1'])) {
     478                $opcodes[$i]['op1'] = $this->removeKeyPrefix($opcodes[$i]['op1'], 'u.');
     479                $opcodes[$i]['op2'] = $this->removeKeyPrefix($opcodes[$i]['op2'], 'u.');
     480                $opcodes[$i]['result'] = $this->removeKeyPrefix($opcodes[$i]['result'], 'u.');
     481            }
     482            else {
     483                $op = array(
     484                    'op1' => array(),
     485                    'op2' => array(),
     486                    'op3' => array(),
     487                );
     488                foreach ($opcodes[$i] as $name => $value) {
     489                    if (preg_match('!^(op1|op2|result)\\.(.*)!', $name, $m)) {
     490                        list(, $which, $field) = $m;
     491                        $op[$which][$field] = $value;
     492                    }
     493                    else if (preg_match('!^(op1|op2|result)_type$!', $name, $m)) {
     494                        list(, $which) = $m;
     495                        $op[$which]['op_type'] = $value;
     496                    }
     497                    else {
     498                        $op[$name] = $value;
     499                    }
     500                }
     501                $opcodes[$i] = $op;
     502            }
     503        }
    463504        // {{{ build jmp array
    464505        for ($i = 0, $cnt = count($opcodes); $i < $cnt; $i ++) {
     
    474515            switch ($op['opcode']) {
    475516            case XC_JMP:
    476                 $target = $op['op1']['u.var'];
     517                $target = $op['op1']['var'];
    477518                $op['jmpouts'] = array($target);
    478519                $opcodes[$target]['jmpins'][] = $i;
     
    480521
    481522            case XC_JMPZNZ:
    482                 $jmpz = $op['op2']['u.opline_num'];
     523                $jmpz = $op['op2']['opline_num'];
    483524                $jmpnz = $op['extended_value'];
    484525                $op['jmpouts'] = array($jmpz, $jmpnz);
     
    494535            case XC_FE_FETCH:
    495536            // case XC_JMP_NO_CTOR:
    496                 $target = $op['op2']['u.opline_num'];
     537                $target = $op['op2']['opline_num'];
    497538                //if (!isset($target)) {
    498539                //  $this->dumpop($op, $EX);
     
    581622        if ($op['opcode'] == XC_FE_FETCH) {
    582623            $opline = $next;
    583             $next = $op['op2']['u.opline_num'];
     624            $next = $op['op2']['opline_num'];
    584625            $end = $next - 1;
    585626
     
    600641        /*
    601642        if ($op['opcode'] == XC_JMPZ) {
    602             $target = $op2['u.opline_num'];
     643            $target = $op2['opline_num'];
    603644            if ($line + 1) {
    604645                $nextblock = $EX['nextbbs'][$next];
    605646                $jmpop = end($nextblock);
    606647                if ($jmpop['opcode'] == XC_JMP) {
    607                     $ifendline = $op2['u.opline_num'];
     648                    $ifendline = $op2['opline_num'];
    608649                    if ($ifendline >= $line) {
    609650                        $cond = $op['cond'];
     
    650691                }
    651692
    652                 $var = $fromop['result']['u.var'];
     693                $var = $fromop['result']['var'];
    653694                var_dump($EX['Ts'][$var]);
    654695                $EX['Ts'][$var] = '(' . $fromop['and_or'] . " $opstr " . $EX['Ts'][$var] . ')';
     
    712753
    713754            $resvar = null;
    714             if (($res['u.EA.type'] & EXT_TYPE_UNUSED) || $res['op_type'] == XC_IS_UNUSED) {
     755            if (isset($res['EA.type']) && ($res['EA.type'] & EXT_TYPE_UNUSED) || $res['op_type'] == XC_IS_UNUSED) {
    715756                $istmpres = false;
    716757            }
     
    743784                case XC_NEW: // {{{
    744785                    array_push($EX['arg_types_stack'], array($EX['object'], $EX['fbc']));
    745                     $EX['object'] = (int) $res['u.var'];
     786                    $EX['object'] = (int) $res['var'];
    746787                    $EX['fbc'] = 'new ' . $this->unquoteName($this->getOpVal($op1, $EX));
    747788                    if (PHP_VERSION < 5) {
     
    761802                    }
    762803                    else {
    763                         $class = $op2['u.constant'];
     804                        $class = $op2['constant'];
    764805                        if (is_object($class)) {
    765806                            $class = get_class($class);
     
    771812                case XC_FETCH_CONSTANT: // {{{
    772813                    if ($op1['op_type'] == XC_IS_CONST) {
    773                         $resvar = $op1['u.constant'];
     814                        $resvar = $op1['constant'];
    774815                    }
    775816                    else if ($op1['op_type'] == XC_IS_UNUSED) {
    776                         $resvar = $op2['u.constant'];
     817                        $resvar = $op2['constant'];
    777818                    }
    778819                    else {
    779                         $class = $T[$op1['u.var']];
     820                        $class = $T[$op1['var']];
    780821                        assert($class[0] == 'class');
    781                         $resvar = $class[1] . '::' . $op2['u.constant'];
     822                        $resvar = $class[1] . '::' . $op2['constant'];
    782823                    }
    783824                    break;
     
    792833                case XC_UNSET_VAR:
    793834                    $rvalue = $this->getOpVal($op1, $EX);
    794                     $fetchtype = $op2[PHP_VERSION < 5 ? 'u.fetch_type' : 'u.EA.type'];
     835                    $fetchtype = $op2[PHP_VERSION < 5 ? 'fetch_type' : 'EA.type'];
    795836                    switch ($fetchtype) {
    796837                    case ZEND_FETCH_STATIC_MEMBER:
     
    838879
    839880                            $src = new Decompiler_ListBox($list);
    840                             if (!isset($op1['u.var'])) {
     881                            if (!isset($op1['var'])) {
    841882                                $this->dumpop($op, $EX);
    842883                                var_dump($op);
    843                                 die('missing u.var');
     884                                die('missing var');
    844885                            }
    845                             $T[$op1['u.var']] = $src;
     886                            $T[$op1['var']] = $src;
    846887                            unset($list);
    847888                        }
     
    883924                        $type = $rvalue->iskey ? 'fe_key' : 'fe_as';
    884925                        $rvalue->obj[$type] = $lvalue;
    885                         unset($T[$op2['u.var']]);
     926                        unset($T[$op2['var']]);
    886927                        break;
    887928                    }
     
    9691010                            $rvalue = "${" . $rvalue . "}";
    9701011                        }
    971                         if ($op2['u.EA.type'] == ZEND_FETCH_STATIC_MEMBER) {
     1012                        if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) {
    9721013                            $class = $this->getOpVal($op2, $EX);
    9731014                            $rvalue = $class . '::' . $rvalue;
     
    9831024                    }
    9841025
    985                     switch (PHP_VERSION < 5 ? $op['op2']['u.var'] /* u.constant */ : $ext) {
     1026                    switch ((PHP_VERSION < 5 ? $op['op2']['var'] /* constant */ : $ext) & (ZEND_ISSET|ZEND_ISEMPTY)) {
    9861027                    case ZEND_ISSET:
    9871028                        $rvalue = "isset($rvalue)";
     
    9901031                        $rvalue = "empty($rvalue)";
    9911032                        break;
    992                     default:
    993                         $this->dumpop($op, $EX);
    994                         die_error('1');
    9951033                    }
    9961034                    $resvar = $rvalue;
     
    10271065
    10281066                    if ($opc == XC_INIT_FCALL_BY_FUNC) {
    1029                         $which = $op1['u.var'];
     1067                        $which = $op1['var'];
    10301068                        $EX['fbc'] = $EX['op_array']['funcs'][$which]['name'];
    10311069                    }
     
    10361074                    // }}}
    10371075                case XC_DO_FCALL_BY_FUNC:
    1038                     $which = $op1['u.var'];
     1076                    $which = $op1['var'];
    10391077                    $fname = $EX['op_array']['funcs'][$which]['name'];
    10401078                    $args = $this->popargs($EX, $ext);
     
    10691107                    // }}}
    10701108                case XC_VERIFY_ABSTRACT_CLASS: // {{{
    1071                     //unset($T[$op1['u.var']]);
     1109                    //unset($T[$op1['var']]);
    10721110                    break;
    10731111                    // }}}
     
    10751113                case XC_DECLARE_INHERITED_CLASS:
    10761114                case XC_DECLARE_INHERITED_CLASS_DELAYED: // {{{
    1077                     $key = $op1['u.constant'];
     1115                    $key = $op1['constant'];
    10781116                    if (!isset($this->dc['class_table'][$key])) {
    10791117                        echo 'class not found: ', $key, 'existing classes are:', "\n";
     
    10941132                    while ($i + 2 < $ic
    10951133                     && $opcodes[$i + 2]['opcode'] == XC_ADD_INTERFACE
    1096                      && $opcodes[$i + 2]['op1']['u.var'] == $res['u.var']
     1134                     && $opcodes[$i + 2]['op1']['var'] == $res['var']
    10971135                     && $opcodes[$i + 1]['opcode'] == XC_FETCH_CLASS) {
    10981136                        $fetchop = &$opcodes[$i + 1];
     
    11601198                        $offset = $this->getOpVal($op2, $EX);
    11611199                        if (isset($offset)) {
    1162                             $T[$res['u.var']]->value[$offset] = $rvalue;
     1200                            $T[$res['var']]->value[$offset] = $rvalue;
    11631201                        }
    11641202                        else {
    1165                             $T[$res['u.var']]->value[] = $rvalue;
     1203                            $T[$res['var']]->value[] = $rvalue;
    11661204                        }
    11671205                    }
     
    11971235                    // }}}
    11981236                case XC_INCLUDE_OR_EVAL: // {{{
    1199                     $type = $op2['u.var']; // hack
     1237                    $type = $op2['var']; // hack
    12001238                    $keyword = $this->includeTypes[$type];
    12011239                    $resvar = "$keyword(" . $this->getOpVal($op1, $EX) . ")";
     
    12101248                    $fe = new Decompiler_ForeachBox($op);
    12111249                    $fe->iskey = false;
    1212                     $T[$res['u.var']] = $fe;
     1250                    $T[$res['var']] = $fe;
    12131251
    12141252                    ++ $i;
     
    12181256
    12191257                        $res = $opcodes[$i]['result'];
    1220                         $T[$res['u.var']] = $fe;
     1258                        $T[$res['var']] = $fe;
    12211259                    }
    12221260                    break;
    12231261                    // }}}
    12241262                case XC_SWITCH_FREE: // {{{
    1225                     // unset($T[$op1['u.var']]);
     1263                    // unset($T[$op1['var']]);
    12261264                    break;
    12271265                    // }}}
    12281266                case XC_FREE: // {{{
    1229                     $free = $T[$op1['u.var']];
     1267                    $free = $T[$op1['var']];
    12301268                    if (!is_a($free, 'Decompiler_Array') && !is_a($free, 'Decompiler_Box')) {
    12311269                        $op['php'] = is_object($free) ? $free : $this->unquote($free, '(', ')');
    12321270                        $lastphpop = &$op;
    12331271                    }
    1234                     unset($T[$op1['u.var']], $free);
     1272                    unset($T[$op1['var']], $free);
    12351273                    break;
    12361274                    // }}}
     
    12581296                    }
    12591297                    if ($opc == XC_JMPZ_EX || $opc == XC_JMPNZ_EX || $opc == XC_JMPZ) {
    1260                         $targetop = &$EX['opcodes'][$op2['u.opline_num']];
     1298                        $targetop = &$EX['opcodes'][$op2['opline_num']];
    12611299                        if ($opc == XC_JMPNZ_EX) {
    12621300                            $targetop['cond_true'][] = str($rvalue);
     
    12861324                    $lvalue = $this->getOpVal($op['result'], $EX);
    12871325                    if ($opc == XC_RECV_INIT) {
    1288                         $default = value($op['op2']['u.constant']);
     1326                        $default = value($op['op2']['constant']);
    12891327                    }
    12901328                    else {
     
    13721410            if (isset($resvar)) {
    13731411                if ($istmpres) {
    1374                     $T[$res['u.var']] = $resvar;
    1375                     $lastresvar = &$T[$res['u.var']];
     1412                    $T[$res['var']] = $resvar;
     1413                    $lastresvar = &$T[$res['var']];
    13761414                }
    13771415                else {
     
    14191457            switch ($op[$k]['op_type']) {
    14201458            case XC_IS_UNUSED:
    1421                 $d[$kk] = '*UNUSED* ' . $op[$k]['u.opline_num'];
     1459                $d[$kk] = '*UNUSED* ' . $op[$k]['opline_num'];
    14221460                break;
    14231461
    14241462            case XC_IS_VAR:
    1425                 $d[$kk] = '$' . $op[$k]['u.var'];
     1463                $d[$kk] = '$' . $op[$k]['var'];
    14261464                if ($kk != 'res') {
    14271465                    $d[$kk] .= ':' . $this->getOpVal($op[$k], $EX);
     
    14301468
    14311469            case XC_IS_TMP_VAR:
    1432                 $d[$kk] = '#' . $op[$k]['u.var'];
     1470                $d[$kk] = '#' . $op[$k]['var'];
    14331471                if ($kk != 'res') {
    14341472                    $d[$kk] .= ':' . $this->getOpVal($op[$k], $EX);
Note: See TracChangeset for help on using the changeset viewer.