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

decompiler: namespace support

File:
1 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'];
Note: See TracChangeset for help on using the changeset viewer.