Changeset 1302 in svn for trunk/lib/Decompiler.class.php


Ignore:
Timestamp:
2013-07-12T09:23:18Z (2 years ago)
Author:
Xuefer
Message:

Disassembler: can now recover compile time constant

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/Decompiler.class.php

    r1300 r1302  
    2626}
    2727// }}}
     28function unsetArray(&$array, $name) // {{{
     29{
     30    unset($array[$name]);
     31}
     32// }}}
     33
    2834function foldToCode($src, $indent = '') // {{{ wrap or rewrap anything to Decompiler_Code
    2935{
     
    4854}
    4955// }}}
    50 function value($value) // {{{
     56function value($value, &$EX) // {{{
    5157{
    5258    $spec = xcache_get_special_value($value);
     
    6369    }
    6470    else if (is_array($value)) {
    65         $value = new Decompiler_ConstArray($value);
     71        $value = new Decompiler_ConstArray($value, $EX);
    6672    }
    6773    else {
    68         $value = new Decompiler_Value($value);
     74        if (isset($EX['value2constant'][$value])) {
     75            $value = new Decompiler_Code($EX['value2constant'][$value]);
     76        }
     77        else {
     78            $value = new Decompiler_Value($value);
     79        }
    6980    }
    7081    return $value;
     
    441452class Decompiler_ConstArray extends Decompiler_Array // {{{
    442453{
    443     function Decompiler_ConstArray($array)
     454    function Decompiler_ConstArray($array, &$EX)
    444455    {
    445456        $elements = array();
    446457        foreach ($array as $key => $value) {
    447             $elements[] = array(value($key), value($value));
     458            $elements[] = array(value($key, $EX), value($value, $EX));
    448459        }
    449460        $this->value = $elements;
     
    466477    public $namespace;
    467478    public $namespaceDecided;
     479    public $activeClass;
     480    public $activeMethod;
     481    public $activeFunction;
    468482
    469483    function Decompiler()
     
    613627        switch ($op['op_type']) {
    614628        case XC_IS_CONST:
    615             return value($op['constant']);
     629            return value($op['constant'], $EX);
    616630
    617631        case XC_IS_VAR:
     
    13451359        $EX['uses'] = array();
    13461360        $EX['lastBlock'] = null;
     1361        $EX['value2constant'] = array();
     1362        if (isset($this->activeClass)) {
     1363            $EX['value2constant'][$this->activeClass] = '__CLASS__';
     1364        }
     1365        if (isset($this->activeMethod)) {
     1366            $EX['value2constant'][$this->activeMethod] = '__METHOD__';
     1367        }
     1368        if (isset($this->activeFunction)) {
     1369            $EX['value2constant'][$this->activeFunction] = '__FUNCTION__';
     1370        }
    13471371
    13481372        /* dump whole array
     
    13631387        $opcodes = &$EX['opcodes'];
    13641388        $lastphpop = null;
    1365 
    1366         for ($i = $range[0]; $i <= $range[1]; $i ++) {
     1389        $currentSourceLine = null;
     1390
     1391        for ($i = $range[0]; $i <= $range[1]; $i ++, unsetArray($EX['value2constant'], $currentSourceLine)) {
    13671392            // {{{ prepair
    13681393            $op = &$opcodes[$i];
     
    13771402            $res = $op['result'];
    13781403            $ext = $op['extended_value'];
     1404            $currentSourceLine = $op['line'];
     1405            $EX['value2constant'][$currentSourceLine] = '__LINE__';
    13791406
    13801407            $opname = xcache_get_opcode($opc);
     
    14411468                }
    14421469                else {
    1443                     $class = $this->getOpVal($op2, $EX);
    1444                     if (isset($op2['constant'])) {
    1445                         $class = $this->stripNamespace(unquoteName($class));
    1446                     }
     1470                    $class = isset($op2['constant']) ? $op2['constant'] : $this->getOpVal($op2, $EX);
    14471471                }
    14481472                $resvar = $class;
     
    14761500                $fetchtype = defined('ZEND_FETCH_TYPE_MASK') ? ($ext & ZEND_FETCH_TYPE_MASK) : $op2['EA.type'];
    14771501                if ($fetchtype == ZEND_FETCH_STATIC_MEMBER) {
    1478                     $class = $this->getOpVal($op2, $EX);
    1479                     $rvalue = unquoteName(str($class)) . '::$' . unquoteName($rvalue, $EX);
     1502                    $rvalue = $this->stripNamespace($op2['constant']) . '::$' . unquoteName($rvalue, $EX);
    14801503                }
    14811504                else if ($opc != XC_UNSET_VAR) {
     
    16261649                                $var = $statics[$name];
    16271650                                $resvar .= ' = ';
    1628                                 $resvar .= str(value($var), $EX);
     1651                                $resvar .= str(value($var, $EX), $EX);
    16291652                            }
    16301653                            unset($statics);
     
    16741697                    $fetchtype = defined('ZEND_FETCH_TYPE_MASK') ? ($ext & ZEND_FETCH_TYPE_MASK) : $op2['EA.type'];
    16751698                    if ($fetchtype == ZEND_FETCH_STATIC_MEMBER) {
    1676                         $class = $this->getOpVal($op2, $EX);
    1677                         $rvalue = unquoteName(str($class)) . '::' . unquoteName($rvalue, $EX);
     1699                        $rvalue = $this->stripNamespace($op2['constant']) . '::' . unquoteName($rvalue, $EX);
    16781700                    }
    16791701                }
     
    17401762                }
    17411763
    1742                 $EX['fbc'] = $this->getOpVal($op2, $EX);
     1764                $EX['fbc'] = isset($op2['constant']) ? $op2['constant'] : $this->getOpVal($op2, $EX);
    17431765                if (($opc == XC_INIT_STATIC_METHOD_CALL || $opc == XC_INIT_METHOD_CALL) && !isset($EX['fbc'])) {
    17441766                    $EX['fbc'] = '__construct';
     
    18461868                    $i += 2;
    18471869                }
     1870                $this->activeClass = $class['name'];
    18481871                $this->dclass($class, $EX['indent']);
     1872                $this->activeClass = null;
    18491873                echo "\n";
    18501874                unset($class);
     
    18621886                switch ($opc) {
    18631887                case XC_ADD_CHAR:
    1864                     $op2val = value(chr(str($op2val)));
     1888                    $op2val = value(chr(str($op2val)), $EX);
    18651889                    break;
    18661890                case XC_ADD_STRING:
     
    20242048                $lvalue = $this->getOpVal($op['result'], $EX);
    20252049                if ($opc == XC_RECV_INIT) {
    2026                     $default = value($op['op2']['constant']);
     2050                    $default = value($op['op2']['constant'], $EX);
    20272051                }
    20282052                else {
     
    24312455                    echo $newindent;
    24322456                    echo $prefix, $name, ' = ';
    2433                     echo str(value($v), $newindent);
     2457                    echo str(value($v, $EX), $newindent);
    24342458                    echo ";\n";
    24352459                }
     
    25022526                if (isset($value)) {
    25032527                    echo ' = ';
    2504                     echo str(value($value), $newindent);
     2528                    echo str(value($value, $EX), $newindent);
    25052529                }
    25062530                echo ";\n";
     
    25492573                        }
    25502574                    }
     2575                    $this->activeMethod = $this->activeClass . '::' . $opa['function_name'];
     2576                    $this->activeFunction = $opa['function_name'];
    25512577                    $this->dfunction($func, $newindent, $decorations, $isInterface || $isAbstractMethod);
     2578                    $this->activeFunction = null;
     2579                    $this->activeMethod = null;
    25522580                    if ($opa['function_name'] == 'Decompiler') {
    25532581                        //exit;
     
    25912619        foreach ($this->dc['class_table'] as $key => $class) {
    25922620            if ($key{0} != "\0") {
     2621                $this->activeClass = $class['name'];
    25932622                $this->dclass($class);
     2623                $this->activeClass = null;
    25942624                echo "\n";
    25952625            }
     
    25982628        foreach ($this->dc['function_table'] as $key => $func) {
    25992629            if ($key{0} != "\0") {
     2630                $this->activeFunction = $key;
    26002631                $this->dfunction($func);
     2632                $this->activeFunction = null;
    26012633                echo "\n";
    26022634            }
Note: See TracChangeset for help on using the changeset viewer.