Changeset 1302


Ignore:
Timestamp:
2013-07-12T11:23:18+02:00 (13 months ago)
Author:
moo
Message:

Disassembler: can now recover compile time constant

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

    r1296 r1302  
    3737        echo CONST_VALUE; 
    3838        echo ClassName::CONST_VALUE; 
    39         unset(t::$classProp1); 
     39        unset(ClassName::$classProp1); 
    4040        unset($obj->objProp); 
    4141        unset($this->thisProp); 
     
    4646        empty($GLOBALS['a']); 
    4747        unset($GLOBALS['a']); 
     48        isset(ClassName::$a); 
     49        empty(ClassName::$a); 
     50        unset(ClassName::$a); 
    4851        echo $GLOBALS['a']; 
    4952        $obj->objProp = 1; 
     
    5861 
    5962    /** doc */ 
    60     public function method(array $a = NULL, $b = NULL) 
     63    public function method($a = NULL, $b = NULL) 
    6164    { 
    6265    } 
     
    110113        echo __CLASS__; 
    111114        echo __METHOD__; 
     115        echo __FUNCTION__; 
    112116        throw new Exception(); 
    113117        $this->methodCall(); 
     
    122126    static public function __callStatic($name, $args) 
    123127    { 
     128        parent::__callStatic($name, $args); 
    124129    } 
    125130 
    126131    public function __toString() 
    127132    { 
     133        parent::__toString(); 
    128134    } 
    129135 
     
    169175    { 
    170176        echo 'lateFunction'; 
     177        return new lateBindingFunction(); 
    171178    } 
    172179} 
Note: See TracChangeset for help on using the changeset viewer.