Changeset 753


Ignore:
Timestamp:
2011-04-17T06:58:46+02:00 (3 years ago)
Author:
moo
Message:

decompiler: namespace support

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r752 r753  
    7171} 
    7272// }}} 
     73function unquoteName_($str, $asProperty, $indent = '') // {{{ 
     74{ 
     75    $str = str($str, $indent); 
     76    if (preg_match("!^'[\\w_][\\w\\d_\\\\]*'\$!", $str)) { 
     77        return str_replace('\\\\', '\\', substr($str, 1, -1)); 
     78    } 
     79    else if ($asProperty) { 
     80        return "{" . $str . "}"; 
     81    } 
     82    else { 
     83        return $str; 
     84    } 
     85} 
     86// }}} 
    7387function unquoteProperty($str, $indent = '') // {{{ 
    7488{ 
    75     $str = str($str, $indent); 
    76     if (preg_match("!^'[\\w_][\\w\\d_]*'\$!", $str)) { 
    77         return substr($str, 1, -1); 
    78     } 
    79     else { 
    80         return "{" . $str . "}"; 
    81     } 
     89    return unquoteName_($str, true, $indent); 
    8290} 
    8391// }}} 
    8492function unquoteName($str, $indent = '') // {{{ 
    8593{ 
    86     $str = str($str, $indent); 
    87     if (preg_match("!^'[\\w_][\\w\\d_]*'\$!", $str)) { 
    88         return substr($str, 1, -1); 
    89     } 
    90     else { 
    91         return $str; 
    92     } 
     94    return unquoteName_($str, false, $indent); 
    9395} 
    9496// }}} 
     
    423425class Decompiler 
    424426{ 
    425     var $rName = '!^[\\w_][\\w\\d_]*$!'; 
     427    var $namespace; 
     428    var $namespaceDecided; 
    426429 
    427430    function Decompiler() 
     
    473476                // }}} 
    474477    } 
     478    function detectNamespace($name) // {{{ 
     479    { 
     480        if ($this->namespaceDecided) { 
     481            return; 
     482        } 
     483 
     484        if (strpos($name, '\\') !== false) { 
     485            $this->namespace = strtok($name, '\\'); 
     486            echo 'namespace ', $this->namespace, ";\n\n"; 
     487        } 
     488 
     489        $this->namespaceDecided = true; 
     490    } 
     491    // }}} 
     492    function stripNamespace($name) // {{{ 
     493    { 
     494        $len = strlen($this->namespace) + 1; 
     495        if (substr($name, 0, $len) == $this->namespace . '\\') { 
     496            return substr($name, $len); 
     497        } 
     498        else { 
     499            return $name; 
     500        } 
     501    } 
     502    // }}} 
    475503    function outputPhp(&$opcodes, $opline, $last, $indent) // {{{ 
    476504    { 
     
    922950                        $class = $this->getOpVal($op2, $EX); 
    923951                        if (isset($op2['constant'])) { 
    924                             $class = unquoteName($class); 
     952                            $class = $this->stripNamespace(unquoteName($class)); 
    925953                        } 
    926954                    } 
     
    930958                case XC_FETCH_CONSTANT: // {{{ 
    931959                    if ($op1['op_type'] == XC_IS_UNUSED) { 
    932                         $resvar = $op2['constant']; 
     960                        $resvar = $this->stripNamespace($op2['constant']); 
    933961                        break; 
    934962                    } 
    935963 
    936964                    if ($op1['op_type'] == XC_IS_CONST) { 
    937                         $resvar = $op1['constant']; 
     965                        $resvar = $this->stripNamespace($op1['constant']); 
    938966                    } 
    939967                    else { 
     
    11911219                        if ($opc == XC_INIT_STATIC_METHOD_CALL || /* PHP4 */ isset($op1['constant'])) { 
    11921220                            $EX['object'] = null; 
    1193                             $EX['called_scope'] = unquoteName($obj, $EX); 
     1221                            $EX['called_scope'] = $this->stripNamespace(unquoteName($obj, $EX)); 
    11941222                        } 
    11951223                        else { 
     
    12121240                    break; 
    12131241                    // }}} 
     1242                case XC_INIT_NS_FCALL_BY_NAME: 
    12141243                case XC_INIT_FCALL_BY_NAME: // {{{ 
    12151244                    if (!ZEND_ENGINE_2 && ($ext & ZEND_CTOR_CALL)) { 
     
    12491278                    $args = $this->popargs($EX, $ext); 
    12501279 
    1251                     $resvar = 
    1252                         (isset($object) ? $object . '->' : '' ) 
    1253                         . (isset($EX['called_scope']) ? $EX['called_scope'] . '::' : '' ) 
    1254                         . $fname . "($args)"; 
     1280                    $prefix = (isset($object) ? $object . '->' : '' ) 
     1281                        . (isset($EX['called_scope']) ? $EX['called_scope'] . '::' : '' ); 
     1282                    $resvar = $prefix 
     1283                        . (!$prefix ? $this->stripNamespace($fname) : $fname) 
     1284                        . "($args)"; 
    12551285                    unset($args); 
    12561286 
     
    13051335 
    13061336                        $fetchop = &$opcodes[$i + 1]; 
    1307                         $impl = unquoteName($this->getOpVal($fetchop['op2'], $EX), $EX); 
     1337                        $interface = $this->stripNamespace(unquoteName($this->getOpVal($fetchop['op2'], $EX), $EX)); 
    13081338                        $addop = &$opcodes[$i + 2]; 
    1309                         $class['interfaces'][$addop['extended_value']] = $impl; 
     1339                        $class['interfaces'][$addop['extended_value']] = $interface; 
    13101340                        unset($fetchop, $addop); 
    13111341                        $i += 2; 
     
    15771607                    // }}} 
    15781608                case XC_DECLARE_CONST: 
    1579                     $resvar = 'const ' . unquoteName($this->getOpVal($op1, $EX), $EX) . ' = ' . str($this->getOpVal($op2, $EX)); 
     1609                    $name = $this->stripNamespace(unquoteName($this->getOpVal($op1, $EX), $EX)); 
     1610                    $value = str($this->getOpVal($op2, $EX)); 
     1611                    $resvar = 'const ' . $name . ' = ' . $value; 
    15801612                    break; 
    15811613                case XC_DECLARE_FUNCTION_OR_CLASS: 
     
    17091741                $ai = $op_array['arg_info'][$i]; 
    17101742                if (!empty($ai['class_name'])) { 
    1711                     echo $ai['class_name'], ' '; 
     1743                    echo $this->stripNamespace($ai['class_name']), ' '; 
    17121744                    if (!ZEND_ENGINE_2_2 && $ai['allow_null']) { 
    17131745                        echo 'or NULL '; 
     
    17551787    function dfunction($func, $indent = '', $nobody = false) // {{{ 
    17561788    { 
     1789        $this->detectNamespace($func['op_array']['function_name']); 
     1790 
    17571791        if ($nobody) { 
    17581792            $EX = array(); 
     
    17701804        } 
    17711805 
    1772         $functionName = $func['op_array']['function_name']; 
     1806        $functionName = $this->stripNamespace($func['op_array']['function_name']); 
    17731807        if ($functionName == '{closure}') { 
    17741808            $functionName = ''; 
     
    17991833    function dclass($class, $indent = '') // {{{ 
    18001834    { 
     1835        $this->detectNamespace($class['name']); 
     1836 
    18011837        // {{{ class decl 
    18021838        if (!empty($class['doc_comment'])) { 
     
    18191855            } 
    18201856        } 
    1821         echo $isinterface ? 'interface ' : 'class ', $class['name']; 
     1857        echo $isinterface ? 'interface ' : 'class ', $this->stripNamespace($class['name']); 
    18221858        if ($class['parent']) { 
    18231859            echo ' extends ', $class['parent']; 
  • trunk/decompilesample.php

    r752 r753  
    11<?php 
     2 
     3//* >= PHP 5.3 
     4namespace ns; 
     5// */ 
    26 
    37abstract class ClassName 
Note: See TracChangeset for help on using the changeset viewer.