Changeset 737 in svn


Ignore:
Timestamp:
2011-04-11T06:41:04+02:00 (4 years ago)
Author:
Xuefer
Message:

decompiler: fix decompiling runtime array

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Decompiler.class.php

    r736 r737  
    99}
    1010
     11function str($code, $indent = '') // {{{
     12{
     13    if (is_object($code)) {
     14        if (get_class($code) != 'Decompiler_Code') {
     15            $code = toCode($code, $indent);
     16        }
     17        return $code->__toString();
     18    }
     19
     20    return (string) $code;
     21}
     22// }}}
    1123function toCode($src, $indent = '') // {{{
    1224{
     
    2032            exit('no toCode');
    2133        }
    22         return $src->toCode($indent);
    23     }
    24 
    25     return $src;
     34        return new Decompiler_Code($src->toCode($indent));
     35    }
     36
     37    return new Decompiler_Code($src);
    2638}
    2739// }}}
     
    3749    }
    3850
    39     if ($value instanceof Decompiler_Object) {
     51    if (is_a($value, 'Decompiler_Object')) {
    4052        // use as is
    4153    }
    4254    else if (is_array($value)) {
    43         $value = new Decompiler_Array($value);
     55        $value = new Decompiler_ConstArray($value);
    4456    }
    4557    else {
     
    7890
    7991    function toCode($indent)
     92    {
     93        return $this;
     94    }
     95
     96    function __toString()
    8097    {
    8198        return $this->src;
     
    243260class Decompiler_Array extends Decompiler_Value // {{{
    244261{
    245     function Decompiler_Array($value = array())
    246     {
    247         $this->value = $value;
     262    // emenets
     263    function Decompiler_Array()
     264    {
     265        $this->value = array();
    248266    }
    249267
    250268    function toCode($indent)
    251269    {
     270        $subindent = $indent . INDENT;
     271
     272        $elementsCode = array();
     273        $index = 0;
     274        foreach ($this->value as $element) {
     275            list($key, $value) = $element;
     276            if (!isset($key)) {
     277                $key = $index++;
     278            }
     279            $elementsCode[] = array(str($key, $subindent), str($value, $subindent), $key, $value);
     280        }
     281
    252282        $exp = "array(";
    253283        $indent = $indent . INDENT;
     
    255285        $multiline = 0;
    256286        $i = 0;
    257         foreach ($this->value as $k => $v) {
    258             if ($i !== $k) {
     287        foreach ($elementsCode as $element) {
     288            list($keyCode, $valueCode) = $element;
     289            if ((string) $i !== $keyCode) {
    259290                $assocWidth = 1;
     291                break;
    260292            }
    261293            ++$i;
    262294        }
    263         foreach ($this->value as $k => $v) {
     295        foreach ($elementsCode as $element) {
     296            list($keyCode, $valueCode, $key, $value) = $element;
    264297            if ($assocWidth) {
    265                 $len = strlen($k);
     298                $len = strlen($keyCode);
    266299                if ($assocWidth < $len) {
    267300                    $assocWidth = $len;
    268301                }
    269302            }
    270             $spec = xcache_get_special_value($v);
    271             if (is_array(isset($spec) ? $spec : $v)) {
     303            if (is_array($value) || is_a($value, 'Decompiler_Array')) {
    272304                $multiline ++;
    273305            }
    274306        }
    275         if ($assocWidth) {
    276             $assocWidth += 2;
    277         }
    278307
    279308        $i = 0;
    280         $subindent = $indent . INDENT;
    281         foreach ($this->value as $k => $v) {
     309        foreach ($elementsCode as $element) {
     310            list($keyCode, $value) = $element;
    282311            if ($multiline) {
    283312                if ($i) {
     
    293322            }
    294323
    295             $k = var_export($k, true);
    296324            if ($assocWidth) {
    297325                if ($multiline) {
    298                     $exp .= sprintf("%{$assocWidth}s => ", $k);
     326                    $exp .= sprintf("%-{$assocWidth}s => ", $keyCode);
    299327                }
    300328                else {
    301                     $exp .= $k . ' => ';
    302                 }
    303             }
    304 
    305             $exp .= toCode(value($v), $subindent);
     329                    $exp .= $keyCode . ' => ';
     330                }
     331            }
     332
     333            $exp .= $value;
    306334
    307335            $i ++;
     
    314342        }
    315343        return $exp;
     344    }
     345}
     346// }}}
     347class Decompiler_ConstArray extends Decompiler_Array // {{{
     348{
     349    function Decompiler_ConstArray($array)
     350    {
     351        $elements = array();
     352        foreach ($array as $key => $value) {
     353            $elements[] = array(value($key), value($value));
     354        }
     355        $this->value = $elements;
    316356    }
    317357}
     
    12391279
    12401280                    if ($opc == XC_ADD_ARRAY_ELEMENT) {
    1241                         $offset = $this->getOpVal($op2, $EX);
    1242                         if (isset($offset)) {
    1243                             $T[$res['var']]->value[$offset] = $rvalue;
     1281                        $assoc = $this->getOpVal($op2, $EX);
     1282                        if (isset($assoc)) {
     1283                            $T[$res['var']]->value[] = array($assoc, $rvalue);
    12441284                        }
    12451285                        else {
    1246                             $T[$res['var']]->value[] = $rvalue;
     1286                            $T[$res['var']]->value[] = array(null, $rvalue);
    12471287                        }
    12481288                    }
     
    12551295                        }
    12561296
    1257                         $offset = $this->getOpVal($op2, $EX);
    1258                         if (isset($offset)) {
    1259                             $resvar->value[$offset] = $rvalue;
     1297                        $assoc = $this->getOpVal($op2, $EX);
     1298                        if (isset($assoc)) {
     1299                            $resvar->value[] = array($assoc, $rvalue);
    12601300                        }
    12611301                        else {
    1262                             $resvar->value[] = $rvalue;
     1302                            $resvar->value[] = array(null, $rvalue);
    12631303                        }
    12641304                    }
     
    13731413                        $default = null;
    13741414                    }
    1375                     $EX['recvs'][$offset] = array($lvalue, $default);
     1415                    $EX['recvs'][str($offset)] = array($lvalue, $default);
    13761416                    break;
    13771417                case XC_POST_DEC:
  • trunk/decompilesample.php

    r736 r737  
    4646        ))
    4747    {
     48        $runtimeArray = array('1');
     49        $runtimeArray2 = array(
     50            '1',
     51            array()
     52            );
     53        $runtimeArray3 = array(
     54            'a' => '1',
     55            2   => array()
     56            );
    4857        return 'protected';
    4958    }
  • trunk/processor/head.m4

    r719 r737  
    141141#define C_RELAYLINE , __LINE__
    142142')
    143 static inline void xc_calc_string_n(xc_processor_t *processor, zend_uchar type, const zstr str, long size IFASSERT(`, int relayline')) {
     143static inline void xc_calc_string_n(xc_processor_t *processor, zend_uchar type, const zstr const str, long size IFASSERT(`, int relayline')) {
    144144    pushdef(`__LINE__', `relayline')
    145145    int realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
     
    163163/* {{{ xc_store_string_n */
    164164REDEF(`KIND', `store')
    165 static inline zstr xc_store_string_n(xc_processor_t *processor, zend_uchar type, const zstr str, long size IFASSERT(`, int relayline')) {
     165static inline zstr xc_store_string_n(xc_processor_t *processor, zend_uchar type, const zstr const str, long size IFASSERT(`, int relayline')) {
    166166    pushdef(`__LINE__', `relayline')
    167167    int realsize = UNISW(size, (type == IS_UNICODE) ? UBYTES(size) : size);
Note: See TracChangeset for help on using the changeset viewer.