Changeset 331

Show
Ignore:
Timestamp:
08/20/07 15:40:19 (9 months ago)
Author:
bart
Message:

Rewrite the fixup_* functions they no longer use the EAG(mem) global

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/ChangeLog

    r330 r331  
    1515 
    16162007-08-20  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
    17         * Rewrite the calc_* values so it no longer uses the EAG(mem) global. 
     17        * Rewrite the calc_* funtions so they no longer uses the EAG(mem) global. 
     18        * Rewrite the fixup_* functions they no longer use the EAG(mem) global 
    1819 
    19202007-08-19  Bart Vanbrabant <bart.vanbrabant at zoeloelip.be> 
  • eaccelerator/trunk/cache.c

    r330 r331  
    416416                        EAG(mem) = (char *) ((long) p - (long) p->next); 
    417417                        EAG(compress) = 1; 
    418                         fixup_zval(&p->value TSRMLS_CC); 
     418                        fixup_zval(((char *) ((long) p - (long) p->next)), &p->value TSRMLS_CC); 
    419419 
    420420                        if (strcmp(xkey, p->key) != 0) { 
  • eaccelerator/trunk/ea_restore.c

    r291 r331  
    6060dtor_func_t get_zend_destroy_property_info(TSRMLS_D) 
    6161{ 
    62        dtor_func_t property_dtor; 
    63        zend_class_entry dummy_class_entry; 
    64        dummy_class_entry.type = ZEND_USER_CLASS; 
    65  
    66        zend_initialize_class_data(&dummy_class_entry, 1 TSRMLS_CC); 
    67  
    68        property_dtor = dummy_class_entry.properties_info.pDestructor; 
    69  
    70        zend_hash_destroy(&dummy_class_entry.default_properties); 
    71        zend_hash_destroy(&dummy_class_entry.function_table); 
    72        zend_hash_destroy(&dummy_class_entry.constants_table); 
    73        zend_hash_destroy(&dummy_class_entry.properties_info); 
     62    dtor_func_t property_dtor; 
     63    zend_class_entry dummy_class_entry; 
     64    dummy_class_entry.type = ZEND_USER_CLASS; 
     65 
     66    zend_initialize_class_data(&dummy_class_entry, 1 TSRMLS_CC); 
     67 
     68    property_dtor = dummy_class_entry.properties_info.pDestructor; 
     69 
     70    zend_hash_destroy(&dummy_class_entry.default_properties); 
     71    zend_hash_destroy(&dummy_class_entry.function_table); 
     72    zend_hash_destroy(&dummy_class_entry.constants_table); 
     73    zend_hash_destroy(&dummy_class_entry.properties_info); 
    7474#  ifdef ZEND_ENGINE_2_1 
    75        zend_hash_destroy(&dummy_class_entry.default_static_members); 
     75    zend_hash_destroy(&dummy_class_entry.default_static_members); 
    7676#  endif 
    7777#  if defined(ZEND_ENGINE_2) && !defined(ZEND_ENGINE_2_1) 
    78        zend_hash_destroy(dummy_class_entry.static_members); 
     78    zend_hash_destroy(dummy_class_entry.static_members); 
    7979        FREE_HASHTABLE(dummy_class_entry.static_members); 
    8080#  endif 
    81        return property_dtor; 
     81    return property_dtor; 
    8282} 
    8383#endif 
     
    8787/******************************************************************************/ 
    8888 
    89 typedef void (*fixup_bucket_t) (void *TSRMLS_DC); 
    90  
    91 #define fixup_zval_hash(from) \ 
    92     fixup_hash(from, (fixup_bucket_t)fixup_zval TSRMLS_CC) 
    93  
    94 #ifdef ZEND_ENGINE_2 
    95 static void fixup_property_info(zend_property_info * from TSRMLS_DC) 
    96 { 
    97        FIXUP(from->name); 
     89typedef void (*fixup_bucket_t) (char *, void *TSRMLS_DC); 
     90 
     91#define fixup_zval_hash(base, from) \ 
     92    fixup_hash(base, from, (fixup_bucket_t)fixup_zval TSRMLS_CC) 
     93 
     94#ifdef ZEND_ENGINE_2 
     95static void fixup_property_info(char *base, zend_property_info * from TSRMLS_DC) 
     96{ 
     97    FIXUP(base, from->name); 
    9898#ifdef ZEND_ENGINE_2_1 
    99         FIXUP(from->doc_comment); 
    100 #endif 
    101 
    102 #endif 
    103  
    104 static void fixup_hash(HashTable * source, 
    105                                            fixup_bucket_t fixup_bucket TSRMLS_DC) 
    106 
    107         unsigned int i; 
    108         Bucket *p; 
    109  
    110         if (source->nNumOfElements > 0) { 
    111                 if (!EAG(compress)) { 
    112                         if (source->arBuckets != NULL) { 
    113                                 FIXUP(source->arBuckets); 
    114                                 for (i = 0; i < source->nTableSize; i++) { 
    115                                         FIXUP(source->arBuckets[i]); 
    116                                 } 
    117                         } 
    118                 } 
    119                 FIXUP(source->pListHead); 
    120                 FIXUP(source->pListTail); 
    121  
    122                 p = source->pListHead; 
    123                 while (p) { 
    124                         FIXUP(p->pNext); 
    125                         FIXUP(p->pLast); 
    126                         FIXUP(p->pData); 
    127                         FIXUP(p->pDataPtr); 
    128                         FIXUP(p->pListLast); 
    129                         FIXUP(p->pListNext); 
    130                         if (p->pDataPtr) { 
    131                                 fixup_bucket(p->pDataPtr TSRMLS_CC); 
    132                                 p->pData = &p->pDataPtr; 
    133                         } else { 
    134                                 fixup_bucket(p->pData TSRMLS_CC); 
    135                         } 
    136                         p = p->pListNext; 
    137                 } 
    138                 source->pInternalPointer = source->pListHead; 
    139         } 
    140 
    141  
    142 void fixup_zval(zval * zv TSRMLS_DC) 
    143 
    144         switch (Z_TYPE_P(zv) & ~IS_CONSTANT_INDEX) { 
    145         case IS_CONSTANT:                       /* fallthrough */ 
    146     case IS_OBJECT:             /* fallthrough: object are serialized */ 
    147         case IS_STRING: 
    148                 FIXUP(Z_STRVAL_P(zv)); 
    149                 break; 
    150         case IS_ARRAY:                          /* fallthrough */ 
    151         case IS_CONSTANT_ARRAY: 
    152                 FIXUP(Z_ARRVAL_P(zv)); 
    153                 fixup_zval_hash(Z_ARRVAL_P(zv)); 
    154                 break; 
    155         default: 
    156                 break; 
    157         } 
    158 
    159  
    160 static void fixup_op_array(ea_op_array * from TSRMLS_DC) 
    161 
    162         zend_op *opline; 
    163         zend_op *end; 
    164  
    165 #ifdef ZEND_ENGINE_2 
    166         if (from->num_args > 0) { 
    167                 zend_uint i; 
    168                 FIXUP(from->arg_info); 
    169                 for (i = 0; i < from->num_args; i++) { 
    170                         FIXUP(from->arg_info[i].name); 
    171                         FIXUP(from->arg_info[i].class_name); 
    172                 } 
    173         } 
    174 #else 
    175         FIXUP(from->arg_types); 
    176 #endif 
    177         FIXUP(from->function_name); 
    178 #ifdef ZEND_ENGINE_2 
    179         FIXUP(from->scope_name); 
    180 #endif 
    181         if (from->type == ZEND_INTERNAL_FUNCTION) { 
    182                 return; 
    183         } 
    184  
    185         if (from->opcodes != NULL) { 
    186                 FIXUP(from->opcodes); 
    187  
    188                 opline = from->opcodes; 
    189                 end = opline + from->last; 
    190                 EAG(compress) = 0; 
    191                 for (; opline < end; opline++) { 
    192                         /* 
    193                            if (opline->result.op_type == IS_CONST)  
    194                            fixup_zval(&opline->result.u.constant TSRMLS_CC); 
    195                          */ 
    196                         if (opline->op1.op_type == IS_CONST) 
    197                                 fixup_zval(&opline->op1.u.constant TSRMLS_CC); 
    198                         if (opline->op2.op_type == IS_CONST) 
    199                                 fixup_zval(&opline->op2.u.constant TSRMLS_CC); 
    200 #ifdef ZEND_ENGINE_2 
    201                         switch (opline->opcode) { 
    202                         case ZEND_JMP: 
    203                                 FIXUP(opline->op1.u.jmp_addr); 
    204                                 break; 
    205                         case ZEND_JMPZ: /* fallthrough */ 
    206                         case ZEND_JMPNZ: 
    207                         case ZEND_JMPZ_EX: 
    208                         case ZEND_JMPNZ_EX: 
    209                                 FIXUP(opline->op2.u.jmp_addr); 
    210                                 break; 
    211                         } 
     99    FIXUP(base, from->doc_comment); 
     100#endif 
     101
     102#endif 
     103 
     104static void fixup_hash(char *base, HashTable * source, 
     105                       fixup_bucket_t fixup_bucket TSRMLS_DC) 
     106
     107    unsigned int i; 
     108    Bucket *p; 
     109 
     110    if (source->nNumOfElements > 0) { 
     111        if (!EAG(compress)) { 
     112            if (source->arBuckets != NULL) { 
     113                FIXUP(base, source->arBuckets); 
     114                for (i = 0; i < source->nTableSize; i++) { 
     115                    FIXUP(base, source->arBuckets[i]); 
     116                } 
     117            } 
     118        } 
     119        FIXUP(base, source->pListHead); 
     120        FIXUP(base, source->pListTail); 
     121 
     122        p = source->pListHead; 
     123        while (p) { 
     124            FIXUP(base, p->pNext); 
     125            FIXUP(base, p->pLast); 
     126            FIXUP(base, p->pData); 
     127            FIXUP(base, p->pDataPtr); 
     128            FIXUP(base, p->pListLast); 
     129            FIXUP(base, p->pListNext); 
     130            if (p->pDataPtr) { 
     131                fixup_bucket(base, p->pDataPtr TSRMLS_CC); 
     132                p->pData = &p->pDataPtr; 
     133            } else { 
     134                fixup_bucket(base, p->pData TSRMLS_CC); 
     135            } 
     136            p = p->pListNext; 
     137        } 
     138        source->pInternalPointer = source->pListHead; 
     139    } 
     140
     141 
     142void fixup_zval(char *base, zval * zv TSRMLS_DC) 
     143
     144    switch (Z_TYPE_P(zv) & ~IS_CONSTANT_INDEX) { 
     145        case IS_CONSTANT:           /* fallthrough */ 
     146        case IS_OBJECT:             /* fallthrough: object are serialized */ 
     147        case IS_STRING: 
     148            FIXUP(base, Z_STRVAL_P(zv)); 
     149            break; 
     150 
     151        case IS_ARRAY:              /* fallthrough */ 
     152        case IS_CONSTANT_ARRAY: 
     153            FIXUP(base, Z_ARRVAL_P(zv)); 
     154            fixup_zval_hash(base, Z_ARRVAL_P(zv)); 
     155            break; 
     156 
     157        default: 
     158            break; 
     159    } 
     160
     161 
     162static void fixup_op_array(char *base, ea_op_array * from TSRMLS_DC) 
     163
     164    zend_op *opline; 
     165    zend_op *end; 
     166 
     167#ifdef ZEND_ENGINE_2 
     168    if (from->num_args > 0) { 
     169        zend_uint i; 
     170        FIXUP(base, from->arg_info); 
     171        for (i = 0; i < from->num_args; i++) { 
     172            FIXUP(base, from->arg_info[i].name); 
     173            FIXUP(base, from->arg_info[i].class_name); 
     174        } 
     175    } 
     176#else 
     177    FIXUP(base, from->arg_types); 
     178#endif 
     179    FIXUP(base, from->function_name); 
     180#ifdef ZEND_ENGINE_2 
     181    FIXUP(base, from->scope_name); 
     182#endif 
     183    if (from->type == ZEND_INTERNAL_FUNCTION) { 
     184        return; 
     185    } 
     186 
     187    if (from->opcodes != NULL) { 
     188        FIXUP(base, from->opcodes); 
     189 
     190        opline = from->opcodes; 
     191        end = opline + from->last; 
     192        EAG(compress) = 0; 
     193        for (; opline < end; opline++) { 
     194            /* 
     195               if (opline->result.op_type == IS_CONST)  
     196               fixup_zval(&opline->result.u.constant TSRMLS_CC); 
     197             */ 
     198            if (opline->op1.op_type == IS_CONST) 
     199                fixup_zval(base, &opline->op1.u.constant TSRMLS_CC); 
     200            if (opline->op2.op_type == IS_CONST) 
     201                fixup_zval(base, &opline->op2.u.constant TSRMLS_CC); 
     202#ifdef ZEND_ENGINE_2 
     203            switch (opline->opcode) { 
     204            case ZEND_JMP: 
     205                FIXUP(base, opline->op1.u.jmp_addr); 
     206                break; 
     207            case ZEND_JMPZ: /* fallthrough */ 
     208            case ZEND_JMPNZ: 
     209            case ZEND_JMPZ_EX: 
     210            case ZEND_JMPNZ_EX: 
     211                FIXUP(base, opline->op2.u.jmp_addr); 
     212                break; 
     213            } 
    212214#  ifdef ZEND_ENGINE_2_1 
    213                        ZEND_VM_SET_OPCODE_HANDLER(opline); 
     215            ZEND_VM_SET_OPCODE_HANDLER(opline); 
    214216#  elif defined(ZEND_ENGINE_2) 
    215217            opline->handler = zend_opcode_handlers[opline->opcode]; 
    216218#  else 
    217                        opline->handler = get_opcode_handler(opline->opcode TSRMLS_CC); 
     219            opline->handler = get_opcode_handler(opline->opcode TSRMLS_CC); 
    218220#  endif 
    219221 
    220222#endif 
    221                
    222                EAG(compress) = 1; 
    223        
    224        FIXUP(from->brk_cont_array); 
    225 #ifdef ZEND_ENGINE_2 
    226        FIXUP(from->try_catch_array); 
    227 #endif 
    228        if (from->static_variables != NULL) { 
    229                FIXUP(from->static_variables); 
    230                fixup_zval_hash(from->static_variables); 
    231        
     223       
     224        EAG(compress) = 1; 
     225   
     226    FIXUP(base, from->brk_cont_array); 
     227#ifdef ZEND_ENGINE_2 
     228    FIXUP(base, from->try_catch_array); 
     229#endif 
     230    if (from->static_variables != NULL) { 
     231        FIXUP(base, from->static_variables); 
     232        fixup_zval_hash(base, from->static_variables); 
     233   
    232234#ifdef ZEND_ENGINE_2_1 
    233        if (from->vars != NULL) { 
    234                int i; 
    235                FIXUP(from->vars); 
    236                for (i = 0; i < from->last_var; i++) { 
    237                        FIXUP(from->vars[i].name); 
    238                
    239        
    240 #endif 
    241        FIXUP(from->filename); 
     235    if (from->vars != NULL) { 
     236        int i; 
     237        FIXUP(base, from->vars); 
     238        for (i = 0; i < from->last_var; i++) { 
     239            FIXUP(base, from->vars[i].name); 
     240       
     241   
     242#endif 
     243    FIXUP(base, from->filename); 
    242244#ifdef INCLUDE_DOC_COMMENTS 
    243245#ifdef ZEND_ENGINE_2 
    244     FIXUP(from->doc_comment); 
    245 #endif 
    246 #endif 
    247 } 
    248  
    249 static void fixup_class_entry(ea_class_entry *from TSRMLS_DC) 
    250 { 
    251        FIXUP(from->name); 
    252        FIXUP(from->parent); 
    253 #ifdef ZEND_ENGINE_2 
    254        FIXUP(from->filename); 
    255        fixup_zval_hash(&from->constants_table); 
    256        fixup_zval_hash(&from->default_properties); 
    257        fixup_hash(&from->properties_info, 
    258                           (fixup_bucket_t) fixup_property_info TSRMLS_CC); 
     246    FIXUP(base, from->doc_comment); 
     247#endif 
     248#endif 
     249} 
     250 
     251static void fixup_class_entry(char *base, ea_class_entry *from TSRMLS_DC) 
     252{ 
     253    FIXUP(base, from->name); 
     254    FIXUP(base, from->parent); 
     255#ifdef ZEND_ENGINE_2 
     256    FIXUP(base, from->filename); 
     257    fixup_zval_hash(base, &from->constants_table); 
     258    fixup_zval_hash(base, &from->default_properties); 
     259    fixup_hash(base, &from->properties_info, 
     260               (fixup_bucket_t) fixup_property_info TSRMLS_CC); 
    259261#  ifdef ZEND_ENGINE_2_1 
    260        fixup_zval_hash(&from->default_static_members); 
    261        if (from->static_members != NULL) { 
    262                FIXUP(from->static_members); 
    263                if (from->static_members != &from->default_static_members) { 
    264                        fixup_zval_hash(from->static_members); 
    265                
    266        
     262    fixup_zval_hash(base, &from->default_static_members); 
     263    if (from->static_members != NULL) { 
     264        FIXUP(base, from->static_members); 
     265        if (from->static_members != &from->default_static_members) { 
     266            fixup_zval_hash(base, from->static_members); 
     267       
     268   
    267269#  else 
    268        if (from->static_members != NULL) { 
    269                FIXUP(from->static_members); 
    270                fixup_zval_hash(from->static_members); 
    271        
     270    if (from->static_members != NULL) { 
     271        FIXUP(base, from->static_members); 
     272        fixup_zval_hash(base, from->static_members); 
     273   
    272274#  endif 
    273275#else 
    274        fixup_zval_hash(&from->default_properties); 
    275 #endif 
    276         fixup_hash(&from->function_table, 
    277                            (fixup_bucket_t) fixup_op_array TSRMLS_CC); 
    278 
    279  
    280 void eaccelerator_fixup (ea_cache_entry *p TSRMLS_DC) 
    281 
    282        ea_fc_entry *q
    283  
    284        EAG (mem) = (char *) ((long) p - (long) p->next); 
    285        EAG (compress) = 1; 
    286        p->next = NULL; 
    287        FIXUP (p->op_array); 
    288        FIXUP (p->f_head); 
    289        FIXUP (p->c_head); 
    290        fixup_op_array (p->op_array TSRMLS_CC); 
    291        q = p->f_head; 
    292        while (q != NULL) { 
    293            FIXUP (q->fc); 
    294            fixup_op_array ((ea_op_array *) q->fc TSRMLS_CC); 
    295            FIXUP (q->next); 
    296            q = q->next; 
    297        
    298        q = p->c_head; 
    299        while (q != NULL) { 
    300            FIXUP (q->fc); 
    301            fixup_class_entry ((ea_class_entry *) q->fc TSRMLS_CC); 
    302            FIXUP (q->next); 
    303            q = q->next; 
    304        
     276    fixup_zval_hash(base, &from->default_properties); 
     277#endif 
     278    fixup_hash(base, &from->function_table,(fixup_bucket_t) fixup_op_array TSRMLS_CC); 
     279
     280 
     281void eaccelerator_fixup(ea_cache_entry *p TSRMLS_DC) 
     282
     283    ea_fc_entry *q; 
     284    char *base
     285 
     286    base = (char *) ((long) p - (long) p->next); 
     287    EAG(compress) = 1; 
     288    p->next = NULL; 
     289    FIXUP(base, p->op_array); 
     290    FIXUP(base, p->f_head); 
     291    FIXUP(base, p->c_head); 
     292    fixup_op_array(base, p->op_array TSRMLS_CC); 
     293    q = p->f_head; 
     294    while (q != NULL) { 
     295        FIXUP(base, q->fc); 
     296        fixup_op_array(base, (ea_op_array *) q->fc TSRMLS_CC); 
     297        FIXUP(base, q->next); 
     298        q = q->next; 
     299   
     300    q = p->c_head; 
     301    while (q != NULL) { 
     302        FIXUP(base, q->fc); 
     303        fixup_class_entry(base, (ea_class_entry *) q->fc TSRMLS_CC); 
     304        FIXUP(base, q->next); 
     305        q = q->next; 
     306   
    305307} 
    306308 
     
    316318static zval *restore_zval_ptr(zval * from TSRMLS_DC) 
    317319{ 
    318        zval *p; 
    319        ALLOC_ZVAL(p); 
    320        memcpy(p, from, sizeof(zval)); 
    321        restore_zval(p TSRMLS_CC); 
    322        /* hrak: reset refcount to make sure there is one reference to this val, and prevent memleaks */ 
    323        p->refcount = 1; 
    324        return p; 
     320    zval *p; 
     321    ALLOC_ZVAL(p); 
     322    memcpy(p, from, sizeof(zval)); 
     323    restore_zval(p TSRMLS_CC); 
     324    /* hrak: reset refcount to make sure there is one reference to this val, and prevent memleaks */ 
     325    p->refcount = 1; 
     326    return p; 
    325327} 
    326328 
    327329static HashTable *restore_hash(HashTable * target, HashTable * source, 
    328                                                           restore_bucket_t copy_bucket TSRMLS_DC) 
    329 { 
    330        Bucket *p, *np, *prev_p; 
    331        int nIndex; 
    332  
    333        if (target == NULL) { 
    334                ALLOC_HASHTABLE(target); 
    335        
    336        memcpy(target, source, sizeof(HashTable)); 
    337        target->arBuckets = 
    338                (Bucket **) emalloc(target->nTableSize * sizeof(Bucket *)); 
    339        memset(target->arBuckets, 0, target->nTableSize * sizeof(Bucket *)); 
    340        target->pDestructor = NULL; 
    341        target->persistent = 0; 
    342        target->pListHead = NULL; 
    343        target->pListTail = NULL; 
     330                               restore_bucket_t copy_bucket TSRMLS_DC) 
     331{ 
     332    Bucket *p, *np, *prev_p; 
     333    int nIndex; 
     334 
     335    if (target == NULL) { 
     336        ALLOC_HASHTABLE(target); 
     337   
     338    memcpy(target, source, sizeof(HashTable)); 
     339    target->arBuckets = 
     340        (Bucket **) emalloc(target->nTableSize * sizeof(Bucket *)); 
     341    memset(target->arBuckets, 0, target->nTableSize * sizeof(Bucket *)); 
     342    target->pDestructor = NULL; 
     343    target->persistent = 0; 
     344    target->pListHead = NULL; 
     345    target->pListTail = NULL; 
    344346#if HARDENING_PATCH_HASH_PROTECT 
    345347    target->canary = zend_hash_canary; 
    346348#endif 
    347349 
    348        p = source->pListHead; 
    349        prev_p = NULL; 
    350        np = NULL; 
    351        while (p) { 
    352                np = (Bucket *) emalloc(offsetof(Bucket, arKey) + p->nKeyLength); 
    353                /*    np = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength); */ 
    354                nIndex = p->h % source->nTableSize; 
    355                if (target->arBuckets[nIndex]) { 
    356                        np->pNext = target->arBuckets[nIndex]; 
    357                        np->pLast = NULL; 
    358                        np->pNext->pLast = np; 
    359                } else { 
    360                        np->pNext = NULL; 
    361                        np->pLast = NULL; 
    362                
    363                target->arBuckets[nIndex] = np; 
    364                np->h = p->h; 
    365                np->nKeyLength = p->nKeyLength; 
    366  
    367                if (p->pDataPtr == NULL) { 
    368                        np->pData = copy_bucket(p->pData TSRMLS_CC); 
    369                        np->pDataPtr = NULL; 
    370                } else { 
    371                        np->pDataPtr = copy_bucket(p->pDataPtr TSRMLS_CC); 
    372                        np->pData = &np->pDataPtr; 
    373                
    374                np->pListLast = prev_p; 
    375                np->pListNext = NULL; 
    376  
    377                memcpy(np->arKey, p->arKey, p->nKeyLength); 
    378  
    379                if (prev_p) { 
    380                        prev_p->pListNext = np; 
    381                } else { 
    382                        target->pListHead = np; 
    383                
    384                prev_p = np; 
    385                p = p->pListNext; 
    386        
    387        target->pListTail = np; 
    388        target->pInternalPointer = target->pListHead; 
    389        return target; 
     350    p = source->pListHead; 
     351    prev_p = NULL; 
     352    np = NULL; 
     353    while (p) { 
     354        np = (Bucket *) emalloc(offsetof(Bucket, arKey) + p->nKeyLength); 
     355        /*    np = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength); */ 
     356        nIndex = p->h % source->nTableSize; 
     357        if (target->arBuckets[nIndex]) { 
     358            np->pNext = target->arBuckets[nIndex]; 
     359            np->pLast = NULL; 
     360            np->pNext->pLast = np; 
     361        } else { 
     362            np->pNext = NULL; 
     363            np->pLast = NULL; 
     364       
     365        target->arBuckets[nIndex] = np; 
     366        np->h = p->h; 
     367        np->nKeyLength = p->nKeyLength; 
     368 
     369        if (p->pDataPtr == NULL) { 
     370            np->pData = copy_bucket(p->pData TSRMLS_CC); 
     371            np->pDataPtr = NULL; 
     372        } else { 
     373            np->pDataPtr = copy_bucket(p->pDataPtr TSRMLS_CC); 
     374            np->pData = &np->pDataPtr; 
     375       
     376        np->pListLast = prev_p; 
     377        np->pListNext = NULL; 
     378 
     379        memcpy(np->arKey, p->arKey, p->nKeyLength); 
     380 
     381        if (prev_p) { 
     382            prev_p->pListNext = np; 
     383        } else { 
     384            target->pListHead = np; 
     385       
     386        prev_p = np; 
     387        p = p->pListNext; 
     388   
     389    target->pListTail = np; 
     390    target->pInternalPointer = target->pListHead; 
     391    return target; 
    390392} 
    391393 
    392394void restore_zval(zval * zv TSRMLS_DC) 
    393395{ 
    394        switch (zv->type & ~IS_CONSTANT_INDEX) { 
    395        case IS_CONSTANT: 
     396    switch (zv->type & ~IS_CONSTANT_INDEX) { 
     397    case IS_CONSTANT: 
    396398    case IS_OBJECT: 
    397        case IS_STRING: 
    398                if (Z_STRVAL_P(zv) == NULL || Z_STRVAL_P(zv) == "" || Z_STRLEN_P(zv) == 0) { 
    399                        Z_STRLEN_P(zv) = 0; 
    400                        Z_STRVAL_P(zv) = empty_string; 
    401                        return; 
    402                } else { 
    403                        char *p = emalloc(Z_STRLEN_P(zv) + 1); 
    404                        memcpy(p, Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1); 
    405                        Z_STRVAL_P(zv) = p; 
    406                
    407                return; 
    408  
    409        case IS_ARRAY: 
    410        case IS_CONSTANT_ARRAY: 
    411                if (Z_ARRVAL_P(zv) != NULL && Z_ARRVAL_P(zv) != &EG(symbol_table)) { 
    412                        Z_ARRVAL_P(zv) = restore_zval_hash(NULL, Z_ARRVAL_P(zv)); 
    413                        Z_ARRVAL_P(zv)->pDestructor = ZVAL_PTR_DTOR; 
    414                
    415                return; 
    416        
     399    case IS_STRING: 
     400        if (Z_STRVAL_P(zv) == NULL || Z_STRVAL_P(zv) == "" || Z_STRLEN_P(zv) == 0) { 
     401            Z_STRLEN_P(zv) = 0; 
     402            Z_STRVAL_P(zv) = empty_string; 
     403            return; 
     404        } else { 
     405            char *p = emalloc(Z_STRLEN_P(zv) + 1); 
     406            memcpy(p, Z_STRVAL_P(zv), Z_STRLEN_P(zv) + 1); 
     407            Z_STRVAL_P(zv) = p; 
     408       
     409        return; 
     410 
     411    case IS_ARRAY: 
     412    case IS_CONSTANT_ARRAY: 
     413        if (Z_ARRVAL_P(zv) != NULL && Z_ARRVAL_P(zv) != &EG(symbol_table)) { 
     414            Z_ARRVAL_P(zv) = restore_zval_hash(NULL, Z_ARRVAL_P(zv)); 
     415            Z_ARRVAL_P(zv)->pDestructor = ZVAL_PTR_DTOR; 
     416       
     417        return; 
     418   
    417419} 
    418420 
    419421static void call_op_array_ctor_handler(zend_extension * extension, 
    420                                                                           zend_op_array * op_array TSRMLS_DC) 
    421 { 
    422        if (extension->op_array_ctor) { 
    423                extension->op_array_ctor(op_array); 
    424        
     422                                       zend_op_array * op_array TSRMLS_DC) 
     423{ 
     424    if (extension->op_array_ctor) { 
     425        extension->op_array_ctor(op_array); 
     426   
    425427} 
    426428 
     
    428430{ 
    429431    union { 
    430        zend_function *v; 
     432        zend_function *v; 
    431433        void *ptr; 
    432434    } function; 
    433435#ifdef ZEND_ENGINE_2 
    434        int fname_len = 0; 
    435        char *fname_lc = NULL; 
    436 #endif 
    437  
    438        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    439        DBG(ea_debug_printf, (EA_DEBUG, "[%d] restore_op_array: %s type=%x\n", getpid(), 
    440                                        from->function_name ? from->function_name : "(top)", from->type)); 
    441  
    442        if (from->type == ZEND_INTERNAL_FUNCTION) { 
    443                if (to == NULL) { 
    444                        to = emalloc(sizeof(zend_internal_function)); 
    445                
    446                memset(to, 0, sizeof(zend_internal_function)); 
    447        } else { 
    448                if (to == NULL) { 
    449                        to = emalloc(sizeof(zend_op_array)); 
    450                
    451                memset(to, 0, sizeof(zend_op_array)); 
    452                if (ZendOptimizer) { 
    453                        zend_llist_apply_with_argument(&zend_extensions,  
     436    int fname_len = 0; 
     437    char *fname_lc = NULL; 
     438#endif 
     439 
     440    DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     441    DBG(ea_debug_printf, (EA_DEBUG, "[%d] restore_op_array: %s type=%x\n", getpid(), 
     442                    from->function_name ? from->function_name : "(top)", from->type)); 
     443 
     444    if (from->type == ZEND_INTERNAL_FUNCTION) { 
     445        if (to == NULL) { 
     446            to = emalloc(sizeof(zend_internal_function)); 
     447       
     448        memset(to, 0, sizeof(zend_internal_function)); 
     449    } else { 
     450        if (to == NULL) { 
     451            to = emalloc(sizeof(zend_op_array)); 
     452       
     453        memset(to, 0, sizeof(zend_op_array)); 
     454        if (ZendOptimizer) { 
     455            zend_llist_apply_with_argument(&zend_extensions,  
    454456                    (llist_apply_with_arg_func_t) call_op_array_ctor_handler, to TSRMLS_CC); 
    455                
    456        
    457        to->type = from->type; 
    458 #ifdef ZEND_ENGINE_2 
    459        to->num_args = from->num_args; 
    460        to->required_num_args = from->required_num_args; 
    461        to->arg_info = from->arg_info; 
    462        to->pass_rest_by_reference = from->pass_rest_by_reference; 
    463 #else 
    464        to->arg_types = from->arg_types; 
    465 #endif 
    466        to->function_name = from->function_name; 
    467  
    468 #ifdef ZEND_ENGINE_2 
    469        if (to->function_name) { 
    470                fname_len = strlen(to->function_name); 
    471                fname_lc = zend_str_tolower_dup(to->function_name, fname_len); 
    472        
    473  
    474        to->fn_flags = from->fn_flags; 
    475  
    476        /* segv74: 
    477         * to->scope = EAG(class_entry) 
    478        
    479         * if  from->scope_name == NULL, 
    480         *     ; EAG(class) == NULL  : we are in function or outside function. 
    481         *     ; EAG(class) != NULL  : inherited method not defined in current file, should have to find. 
    482         *                              just LINK (zend_op_array *) to to original entry in parent, 
    483         *                              but, with what? !!! I don't know PARENT CLASS NAME !!!! 
    484        
    485        
    486         * if  from->scope_name != NULL, 
    487         *     ; we are in class member function  
    488        
    489         *     ; we have to find appropriate (zend_class_entry*) to->scope for name from->scope_name 
    490         *     ; if we find in CG(class_table), link to it. 
    491         *     ; if fail, it should be EAG(class_entry) 
    492         *     
    493         * am I right here ? ;-( 
    494         */ 
    495        if (from->scope_name != NULL) { 
     457       
     458   
     459    to->type = from->type; 
     460#ifdef ZEND_ENGINE_2 
     461    to->num_args = from->num_args; 
     462    to->required_num_args = from->required_num_args; 
     463    to->arg_info = from->arg_info; 
     464    to->pass_rest_by_reference = from->pass_rest_by_reference; 
     465#else 
     466    to->arg_types = from->arg_types; 
     467#endif 
     468    to->function_name = from->function_name; 
     469 
     470#ifdef ZEND_ENGINE_2 
     471    if (to->function_name) { 
     472        fname_len = strlen(to->function_name); 
     473        fname_lc = zend_str_tolower_dup(to->function_name, fname_len); 
     474   
     475 
     476    to->fn_flags = from->fn_flags; 
     477 
     478    /* segv74: 
     479    * to->scope = EAG(class_entry) 
     480   
     481    * if  from->scope_name == NULL, 
     482    *     ; EAG(class) == NULL  : we are in function or outside function. 
     483    *     ; EAG(class) != NULL  : inherited method not defined in current file, should have to find. 
     484    *                              just LINK (zend_op_array *) to to original entry in parent, 
     485    *                              but, with what? !!! I don't know PARENT CLASS NAME !!!! 
     486   
     487   
     488    * if  from->scope_name != NULL, 
     489    *     ; we are in class member function  
     490   
     491    *     ; we have to find appropriate (zend_class_entry*) to->scope for name from->scope_name 
     492    *     ; if we find in CG(class_table), link to it. 
     493    *     ; if fail, it should be EAG(class_entry) 
     494    *     
     495    * am I right here ? ;-( 
     496    */ 
     497    if (from->scope_name != NULL) { 
    496498        union { 
    497499            zend_class_entry *v; 
    498500            void *ptr; 
    499501        } scope; 
    500                char *from_scope_lc = zend_str_tolower_dup(from->scope_name, from->scope_name_len); 
     502        char *from_scope_lc = zend_str_tolower_dup(from->scope_name, from->scope_name_len); 
    501503        scope.v = to->scope; 
    502                if (zend_hash_find (CG(class_table), (void *) from_scope_lc, from->scope_name_len + 1, &scope.ptr) == SUCCESS && 
     504        if (zend_hash_find (CG(class_table), (void *) from_scope_lc, from->scope_name_len + 1, &scope.ptr) == SUCCESS && 
    503505                to->scope != NULL) { 
    504                        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    505                        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   found '%s' in hash\n", getpid(), from->scope_name)); 
     506            DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     507            DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   found '%s' in hash\n", getpid(), from->scope_name)); 
    506508            DBG(ea_debug_printf, (EA_DEBUG, "name=%s :: to->scope is 0x%x", to->function_name, (unsigned int) to->scope)); 
    507                        to->scope = *(zend_class_entry **) to->scope; 
    508                } else { 
     509            to->scope = *(zend_class_entry **) to->scope; 
     510        } else { 
    509511            DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    510512            DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   can't find '%s' in class_table. use EAG(class_entry).\n", getpid(), from->scope_name)); 
    511513            to->scope = EAG(class_entry); 
    512514        } 
    513                efree(from_scope_lc); 
    514        } else { 
     515        efree(from_scope_lc); 
     516    } else { 
    515517        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    516                DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   from is NULL\n", getpid())); 
    517                if (EAG(class_entry)) { 
    518                        zend_class_entry *p; 
    519                        for (p = EAG(class_entry)->parent; p; p = p->parent) { 
    520                                DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    521                                DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   checking parent '%s' have '%s'\n", getpid(), p->name, fname_lc)); 
    522                                if (zend_hash_find(&p->function_table, fname_lc, fname_len + 1, &function.ptr) == SUCCESS) { 
    523                                        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    524                                        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                                   '%s' has '%s' of scope '%s'\n",  
     518        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   from is NULL\n", getpid())); 
     519        if (EAG(class_entry)) { 
     520            zend_class_entry *p; 
     521            for (p = EAG(class_entry)->parent; p; p = p->parent) { 
     522                DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     523                DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   checking parent '%s' have '%s'\n", getpid(), p->name, fname_lc)); 
     524                if (zend_hash_find(&p->function_table, fname_lc, fname_len + 1, &function.ptr) == SUCCESS) { 
     525                    DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     526                    DBG(ea_debug_printf, (EA_DEBUG, "[%d]                                   '%s' has '%s' of scope '%s'\n",  
    525527                            getpid(), p->name, fname_lc, function.v->common.scope->name)); 
    526                                        to->scope = function.v->common.scope; 
    527                                        break; 
    528                                
    529                        
    530                } else { 
    531                        to->scope = NULL; 
    532                
    533        
    534  
    535        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    536        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   %s's scope is '%s'\n", getpid(),  
     528                    to->scope = function.v->common.scope; 
     529                    break; 
     530               
     531           
     532        } else { 
     533            to->scope = NULL; 
     534       
     535   
     536 
     537    DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     538    DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   %s's scope is '%s'\n", getpid(),  
    537539            from->function_name ? from->function_name : "(top)", to->scope ? to->scope->name : "NULL")); 
    538540#endif 
    539        if (from->type == ZEND_INTERNAL_FUNCTION) { 
    540                zend_class_entry *class_entry = EAG(class_entry); 
    541                DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    542                DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   [internal function from=%08x,to=%08x] class_entry='%s' [%08x]\n",  
     541    if (from->type == ZEND_INTERNAL_FUNCTION) { 
     542        zend_class_entry *class_entry = EAG(class_entry); 
     543        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     544        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                   [internal function from=%08x,to=%08x] class_entry='%s' [%08x]\n",  
    543545                getpid(), from, to, class_entry->name, class_entry)); 
    544                if (class_entry) { 
    545                        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    546                        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                                       class_entry->parent='%s' [%08x]\n",  
     546        if (class_entry) { 
     547            DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
     548            DBG(ea_debug_printf, (EA_DEBUG, "[%d]                                       class_entry->parent='%s' [%08x]\n",  
    547549                    getpid(), class_entry->parent->name, class_entry->parent)); 
    548                
    549                if (class_entry != NULL && class_entry->parent != NULL &&  
     550       
     551        if (class_entry != NULL && class_entry->parent != NULL &&  
    550552                zend_hash_find(&class_entry->parent->function_table, 
    551553#ifdef ZEND_ENGINE_2 
     
    554556                to->function_name, strlen(to->function_name) + 1, 
    555557#endif 
    556                                &function.ptr) == SUCCESS && function.v->type == ZEND_INTERNAL_FUNCTION) { 
    557                        DBG(ea_debug_pad, (EA_DEBUG TSRMLS_CC)); 
    558                        DBG(ea_debug_printf, (EA_DEBUG, "[%d]                                       found in function table\n", getpid())); 
    559                        ((zend_internal_function *) (to))->handler = ((zend_internal_function *) function.v)->handler; 
    560                } else { 
    561                        /* FIXME. I don't know how to fix handler. 
    562                         * TODO: must solve this somehow, to avoid returning damaged structure... 
    563