Changeset 761 in svn


Ignore:
Timestamp:
2011-04-17T13:03:00+02:00 (4 years ago)
Author:
Xuefer
Message:

Decompiler: simple cover test, make sure all opcode is tested

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r760 r761  
    7171}
    7272// }}}
    73 function unquoteName_($str, $asProperty, $indent = '') // {{{
     73function unquoteName_($str, $asVariableName, $indent = '') // {{{
    7474{
    7575    $str = str($str, $indent);
     
    7777        return str_replace('\\\\', '\\', substr($str, 1, -1));
    7878    }
    79     else if ($asProperty) {
     79    else if ($asVariableName) {
    8080        return "{" . $str . "}";
    8181    }
     
    8585}
    8686// }}}
    87 function unquoteProperty($str, $indent = '') // {{{
     87function unquoteVariableName($str, $indent = '') // {{{
    8888{
    8989    return unquoteName_($str, true, $indent);
     
    247247        foreach ($this->offsets as $i => $dim) {
    248248            if ($this->isObject && $i == $last) {
    249                 $exp .= '->' . unquoteProperty($dim, $indent);
     249                $exp .= '->' . unquoteVariableName($dim, $indent);
    250250            }
    251251            else {
     
    437437    function Decompiler()
    438438    {
     439        // {{{ testing
     440        // XC_UNDEF XC_OP_DATA
     441        $this->test = !empty($_ENV['XCACHE_DECOMPILER_TEST']);
     442        $this->usedOps = array();
     443
     444        if ($this->test) {
     445            $content = file_get_contents(__FILE__);
     446            for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
     447                if (!preg_match("/\\bXC_" . $opname . "\\b(?!')/", $content)) {
     448                    echo "not recognized opcode ", $opname, "\n";
     449                }
     450            }
     451        }
     452        // }}}
    439453        // {{{ opinfo
    440454        $this->unaryops = array(
     
    619633            $last = count($opcodes) - 1;
    620634            if ($opcodes[$last]['opcode'] == XC_HANDLE_EXCEPTION) {
     635                $this->usedOps[XC_HANDLE_EXCEPTION] = true;
    621636                unset($opcodes[$last]);
    622637                --$last;
     
    882897            $opc = $op['opcode'];
    883898            if ($opc == XC_NOP) {
     899                $this->usedOps[$opc] = true;
    884900                continue;
    885901            }
     
    911927            $call = array(&$this, $opname);
    912928            if (is_callable($call)) {
     929                $this->usedOps[$opc] = true;
    913930                $this->{$opname}($op, $EX);
    914931            }
    915932            else if (isset($this->binops[$opc])) { // {{{
     933                $this->usedOps[$opc] = true;
    916934                $op1val = $this->getOpVal($op1, $EX, false);
    917935                $op2val = $this->getOpVal($op2, $EX, false);
     
    921939            }
    922940            else if (isset($this->unaryops[$opc])) { // {{{
     941                $this->usedOps[$opc] = true;
    923942                $op1val = $this->getOpVal($op1, $EX);
    924943                $myop = $this->unaryops[$opc];
     
    928947            }
    929948            else {
     949                $covered = true;
    930950                switch ($opc) {
    931951                case XC_NEW: // {{{
     
    11651185                        $obj = '$this';
    11661186                    }
    1167                     $rvalue = str($obj) . "->" . unquoteProperty($this->getOpVal($op2, $EX), $EX);
     1187                    $rvalue = str($obj) . "->" . unquoteVariableName($this->getOpVal($op2, $EX), $EX);
    11681188                    if ($res['op_type'] != XC_IS_UNUSED) {
    11691189                        $resvar = $rvalue;
     
    11821202                case XC_ISSET_ISEMPTY_VAR: // {{{
    11831203                    if ($opc == XC_ISSET_ISEMPTY_VAR) {
    1184                         $rvalue = $this->getOpVal($op1, $EX);;
    1185                         if (preg_match($this->rQuotedName, $rvalue)) {
    1186                             $rvalue = '$' . substr($rvalue, 1, -1);
    1187                         }
    1188                         else {
    1189                             $rvalue = '${' . $rvalue . '}';
    1190                         }
     1204                        $rvalue = $this->getOpVal($op1, $EX);
    11911205                        if ($op2['EA.type'] == ZEND_FETCH_STATIC_MEMBER) {
    11921206                            $class = $this->getOpVal($op2, $EX);
     
    12011215                        $dim = $this->getOpVal($op2, $EX);
    12021216                        if ($opc == XC_ISSET_ISEMPTY_PROP_OBJ) {
    1203                             if (preg_match($this->rQuotedName, $dim)) {
    1204                                 $rvalue = $container . "->" . substr($dim, 1, -1);
     1217                            if (!isset($container)) {
     1218                                $container = '$this';
    12051219                            }
    1206                             else {
    1207                                 $rvalue = $container . "->{" . $dim . "}";
    1208                             }
     1220                            $rvalue = $container . "->" . unquoteVariableName($dim);
    12091221                        }
    12101222                        else {
    1211                             $rvalue = $container . "[$dim]";
     1223                            $rvalue = $container . '[' . str($dim) .']';
    12121224                        }
    12131225                    }
     
    13571369                            break;
    13581370                        }
     1371                        $this->usedOps[XC_ADD_INTERFACE] = true;
    13591372
    13601373                        $fetchop = &$opcodes[$i + 1];
     
    14021415                case XC_PRINT: // {{{
    14031416                    $op1val = $this->getOpVal($op1, $EX);
    1404                     $resvar = "print($op1val)";
     1417                    $resvar = "print(" . str($op1val) . ")";
    14051418                    break;
    14061419                    // }}}
     
    15841597                    $flags = array_flip(explode('_', $opname));
    15851598                    if (isset($flags['OBJ'])) {
    1586                         $resvar = $this->getOpVal($op1, $EX) . '->' . unquoteProperty($this->getOpVal($op2, $EX), $EX);
     1599                        $resvar = $this->getOpVal($op1, $EX) . '->' . unquoteVariableName($this->getOpVal($op2, $EX), $EX);
    15871600                    }
    15881601                    else {
     
    16611674                default: // {{{
    16621675                    echo "\x1B[31m * TODO ", $opname, "\x1B[0m\n";
    1663                     // }}}
     1676                    $covered = false;
     1677                    // }}}
     1678                }
     1679                if ($covered) {
     1680                    $this->usedOps[$opc] = true;
    16641681                }
    16651682            }
     
    20792096        $this->dop_array($this->dc['op_array']);
    20802097        echo "\n?" . ">\n";
     2098
     2099        if (!empty($this->test)) {
     2100            $this->outputUnusedOp();
     2101        }
    20812102        return true;
     2103    }
     2104    // }}}
     2105    function outputUnusedOp() // {{{
     2106    {
     2107        for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
     2108            if ($opname == 'UNDEF')  {
     2109                continue;
     2110            }
     2111
     2112            if (!isset($this->usedOps[$i])) {
     2113                echo "not covered opcode ", $opname, "\n";
     2114            }
     2115        }
    20822116    }
    20832117    // }}}
     
    21872221define('IS_LONG',     1);
    21882222define('IS_DOUBLE',   2);
    2189 define('IS_STRING',   3);
     2223define('IS_BOOL',     ZEND_ENGINE_2 ? 3 : 6);
    21902224define('IS_ARRAY',    4);
    21912225define('IS_OBJECT',   5);
    2192 define('IS_BOOL',     6);
     2226define('IS_STRING',   ZEND_ENGINE_2 ? 6 : 3);
    21932227define('IS_RESOURCE', 7);
    21942228define('IS_CONSTANT', 8);
     
    22572291    }
    22582292}
    2259 
    2260 //* XC_UNDEF XC_OP_DATA
    2261 $content = file_get_contents(__FILE__);
    2262 for ($i = 0; $opname = xcache_get_opcode($i); $i ++) {
    2263     if (!preg_match("/\\bXC_" . $opname . "\\b(?!')/", $content)) {
    2264         echo "not done ", $opname, "\n";
    2265     }
    2266 }
    2267 // */
    22682293// }}}
    22692294
  • trunk/decompilesample.php

    r760 r761  
    206206$a = $b xor $c;
    207207$a = !$b;
     208$a = $b === $c;
     209$a = $b !== $c;
     210$a = $b << 2;
     211$a = $b >> 3;
     212$a += $b;
     213$a -= $b;
     214$a *= $b;
     215$a /= $b;
     216$a <<= $b;
     217$a >>= $b;
     218$a &= $b;
     219$a |= $b;
     220$a .= $b;
     221$a %= $b;
     222$a ^= $b;
     223$a = 'a' . 'b';
     224$a = 'a' . 'abc';
     225@f1();
     226print('1');
     227ref(&$a);
     228$a = $array['index'];
     229$a = $object->prop;
     230$a = $this->prop;
     231$array['index'] = 1;
     232$object->prop = 1;
     233$this->prop = 1;
     234$a = isset($b);
     235$a = empty($b);
     236$a = isset($array['index']);
     237$a = empty($array['index']);
     238$a = isset($object->prop);
     239$a = empty($object->prop);
     240$a = isset($this->prop);
     241$a = empty($this->prop);
     242$a = (int) $b;
     243$a = (double) $b;
     244$a = (string) $b;
     245$a = (array) $b;
     246$a = (object) $b;
     247$a = (bool) $b;
     248$a = (unset) $b;
     249$a = (array) $b;
     250$a = (object) $b;
     251// PHP6+ $a = (scalar) $b;
    208252$a = $b ? $c : $d;
    209253$a = f1() ? f2() : f3();
     
    323367};
    324368// */
     369exit();
    325370
    326371?>
Note: See TracChangeset for help on using the changeset viewer.