Show
Ignore:
Timestamp:
07/11/05 19:25:38 (3 years ago)
Author:
zoeloelip
Message:

* ea_store.c and ea_restore.c functions clean up
* extraced restore_class_parent and restore_class_methods from

restore_class_entry to share code with loader.c

* extracted opcode handling in encode/decode_op_array into

encode/decode_op to make code more readable

* make decode_class_entry use new functions in ea_restore.c
* readded line-number encoding
* bumped up encoder version to 4 until new loader is in place

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • eaccelerator/trunk/ea_store.c

    r123 r124  
    4545inline 
    4646#endif 
    47 static void calc_string (char *str, int len TSRMLS_DC) 
    48 
    49     if (len > MAX_DUP_STR_LEN || zend_hash_add (&EAG (strings), str, len,  
    50                 &str, sizeof (char *), NULL) == SUCCESS) { 
    51         EACCELERATOR_ALIGN (EAG (mem)); 
    52         EAG (mem) += len; 
    53     } 
     47static void calc_string(char *str, int len TSRMLS_DC) 
     48
     49        if (len > MAX_DUP_STR_LEN || zend_hash_add(&EAG(strings), str, len, 
     50                                                                                           &str, sizeof(char *), 
     51                                                                                           NULL) == SUCCESS) { 
     52                EACCELERATOR_ALIGN(EAG(mem)); 
     53                EAG(mem) += len; 
     54        } 
    5455} 
    5556 
     
    6970 
    7071 
    71 static void calc_zval_ptr (zval ** from TSRMLS_DC) 
    72 { 
    73     EACCELERATOR_ALIGN (EAG (mem)); 
    74     EAG (mem) += sizeof (zval); 
    75     calc_zval (*from TSRMLS_CC); 
    76 } 
    77  
    78 #ifdef ZEND_ENGINE_2 
    79 static void calc_property_info (zend_property_info * from TSRMLS_DC) 
    80 { 
    81     EACCELERATOR_ALIGN (EAG (mem)); 
    82     EAG (mem) += sizeof (zend_property_info); 
    83     calc_string (from->name, from->name_length + 1 TSRMLS_CC); 
     72static void calc_zval_ptr(zval ** from TSRMLS_DC) 
     73{ 
     74       EACCELERATOR_ALIGN(EAG(mem)); 
     75       EAG(mem) += sizeof(zval); 
     76       calc_zval(*from TSRMLS_CC); 
     77} 
     78 
     79#ifdef ZEND_ENGINE_2 
     80static void calc_property_info(zend_property_info * from TSRMLS_DC) 
     81{ 
     82       EACCELERATOR_ALIGN(EAG(mem)); 
     83       EAG(mem) += sizeof(zend_property_info); 
     84       calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
    8485} 
    8586 
    8687/* Calculate the size of a point to a class entry */ 
    87 static void calc_class_entry_ptr (zend_class_entry ** from TSRMLS_DC) 
    88 { 
    89     calc_class_entry (*from TSRMLS_CC); 
     88static void calc_class_entry_ptr(zend_class_entry ** from TSRMLS_DC) 
     89{ 
     90       calc_class_entry(*from TSRMLS_CC); 
    9091} 
    9192#endif 
    9293 
    9394/* Calculate the size of an HashTable */ 
    94 static void calc_hash_int (HashTable * source, Bucket * start, 
    95                            calc_bucket_t calc_bucket TSRMLS_DC) 
    96 
    97     Bucket *p; 
    98  
    99     if (source->nNumOfElements > 0) { 
    100         if (!EAG (compress)) { 
    101             EACCELERATOR_ALIGN (EAG (mem)); 
    102             EAG (mem) += source->nTableSize * sizeof (Bucket *); 
    103         } 
    104         p = start; 
    105         while (p) { 
    106             EACCELERATOR_ALIGN (EAG (mem)); 
    107             EAG (mem) += offsetof (Bucket, arKey) + p->nKeyLength; 
    108             calc_bucket (p->pData TSRMLS_CC); 
    109             p = p->pListNext; 
    110         } 
    111     } 
    112 
    113  
    114 void calc_zval (zval * zv TSRMLS_DC) 
    115 
    116     switch (zv->type & ~IS_CONSTANT_INDEX) { 
    117     case IS_CONSTANT: 
    118     case IS_STRING: 
    119         if (zv->value.str.val == NULL || 
    120             zv->value.str.val == empty_string || zv->value.str.len == 0) { 
    121         } else { 
    122             calc_string (zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); 
    123         } 
    124         break; 
    125     case IS_ARRAY: 
    126     case IS_CONSTANT_ARRAY: 
    127         if (zv->value.ht == NULL || zv->value.ht == &EG (symbol_table)) { 
    128         } else { 
    129             EACCELERATOR_ALIGN (EAG (mem)); 
    130             EAG (mem) += sizeof (HashTable); 
    131             calc_zval_hash (zv->value.ht); 
    132         } 
    133         break; 
    134     case IS_OBJECT: 
     95static void calc_hash_int(HashTable * source, Bucket * start, 
     96                                                  calc_bucket_t calc_bucket TSRMLS_DC) 
     97
     98        Bucket *p; 
     99 
     100        if (source->nNumOfElements > 0) { 
     101                if (!EAG(compress)) { 
     102                        EACCELERATOR_ALIGN(EAG(mem)); 
     103                        EAG(mem) += source->nTableSize * sizeof(Bucket *); 
     104                } 
     105                p = start; 
     106                while (p) { 
     107                        EACCELERATOR_ALIGN(EAG(mem)); 
     108                        EAG(mem) += offsetof(Bucket, arKey) + p->nKeyLength; 
     109                        calc_bucket(p->pData TSRMLS_CC); 
     110                        p = p->pListNext; 
     111                } 
     112        } 
     113
     114 
     115void calc_zval(zval * zv TSRMLS_DC) 
     116
     117        switch (zv->type & ~IS_CONSTANT_INDEX) { 
     118        case IS_CONSTANT: 
     119        case IS_STRING: 
     120                if (zv->value.str.val == NULL || zv->value.str.val == empty_string || zv->value.str.len == 0) { 
     121                } else { 
     122                        calc_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); 
     123                } 
     124                break; 
     125        case IS_ARRAY: 
     126        case IS_CONSTANT_ARRAY: 
     127                if (zv->value.ht != NULL && zv->value.ht != &EG(symbol_table)) { 
     128                        EACCELERATOR_ALIGN(EAG(mem)); 
     129                        EAG(mem) += sizeof(HashTable); 
     130                        calc_zval_hash(zv->value.ht); 
     131                } 
     132                break; 
     133        case IS_OBJECT: 
    135134#ifndef ZEND_ENGINE_2 
    136         if (zv->value.obj.ce != NULL) { 
    137             zend_class_entry *ce = zv->value.obj.ce; 
    138             if (!EAG (compress)) { 
    139                 ea_debug_error ("[%d] EACCELERATOR can't cache objects\n", 
    140                                 getpid ()); 
    141                 zend_bailout (); 
    142             } 
    143             while (ce != NULL) { 
    144                 if (ce->type != ZEND_USER_CLASS 
    145                     && strcmp (ce->name, "stdClass") != 0) { 
    146                     ea_debug_error ("[%d] EACCELERATOR can't cache objects\n", 
    147                                     getpid ()); 
    148                     zend_bailout (); 
    149                 } 
    150                 ce = ce->parent; 
    151             } 
    152             calc_string (zv->value.obj.ce->name, 
    153                          zv->value.obj.ce->name_length + 1 TSRMLS_CC); 
    154         } 
    155         if (zv->value.obj.properties != NULL) { 
    156             EACCELERATOR_ALIGN (EAG (mem)); 
    157             EAG (mem) += sizeof (HashTable); 
    158             calc_zval_hash (zv->value.obj.properties); 
    159         } 
    160 #endif 
    161         return; 
    162     case IS_RESOURCE: 
    163         ea_debug_error ("[%d] EACCELERATOR can't cache resources\n", getpid ()); 
    164         zend_bailout (); 
    165     default: 
    166         break; 
    167     } 
     135                if (zv->value.obj.ce != NULL) { 
     136                        zend_class_entry *ce = zv->value.obj.ce; 
     137                        if (!EAG(compress)) { 
     138                                ea_debug_error("[%d] EACCELERATOR can't cache objects\n", getpid()); 
     139                                zend_bailout(); 
     140                        } 
     141                        while (ce != NULL) { 
     142                                if (ce->type != ZEND_USER_CLASS && strcmp(ce->name, "stdClass") != 0) { 
     143                                        ea_debug_error("[%d] EACCELERATOR can't cache objects\n", getpid()); 
     144                                        zend_bailout(); 
     145                                } 
     146                                ce = ce->parent; 
     147                        } 
     148                        calc_string(zv->value.obj.ce->name, zv->value.obj.ce->name_length + 1 TSRMLS_CC); 
     149                } 
     150                if (zv->value.obj.properties != NULL) { 
     151                        EACCELERATOR_ALIGN(EAG(mem)); 
     152                        EAG(mem) += sizeof(HashTable); 
     153                        calc_zval_hash(zv->value.obj.properties); 
     154                } 
     155#endif 
     156                return; 
     157        case IS_RESOURCE: 
     158                ea_debug_error("[%d] EACCELERATOR can't cache resources\n", getpid()); 
     159                zend_bailout(); 
     160        default: 
     161                break; 
     162        } 
    168163} 
    169164 
    170165/* Calculate the size of an op_array */ 
    171 void calc_op_array (zend_op_array * from TSRMLS_DC) 
    172 
    173     zend_op *opline; 
    174     zend_op *end; 
    175  
    176     if (from->type == ZEND_INTERNAL_FUNCTION) { 
    177         EACCELERATOR_ALIGN (EAG (mem)); 
    178         EAG (mem) += sizeof (zend_internal_function); 
    179     } else if (from->type == ZEND_USER_FUNCTION) { 
    180         EACCELERATOR_ALIGN (EAG (mem)); 
    181         EAG (mem) += sizeof (eaccelerator_op_array); 
    182     } else { 
    183         ea_debug_error ("[%d] EACCELERATOR can't cache function \"%s\"\n", 
    184                         getpid (), from->function_name); 
    185         zend_bailout (); 
    186     } 
    187 #ifdef ZEND_ENGINE_2 
    188     if (from->num_args > 0) { 
    189         zend_uint i; 
    190         EACCELERATOR_ALIGN (EAG (mem)); 
    191         EAG (mem) += from->num_args * sizeof (zend_arg_info); 
    192         for (i = 0; i < from->num_args; i++) { 
    193             if (from->arg_info[i].name) { 
    194                 calc_string (from->arg_info[i].name, 
    195                              from->arg_info[i].name_len + 1 TSRMLS_CC); 
    196             } 
    197             if (from->arg_info[i].class_name) { 
    198                 calc_string (from->arg_info[i].class_name, 
    199                              from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
    200             } 
    201         } 
    202     } 
     166void calc_op_array(zend_op_array * from TSRMLS_DC) 
     167
     168        zend_op *opline; 
     169        zend_op *end; 
     170 
     171        if (from->type == ZEND_INTERNAL_FUNCTION) { 
     172                EACCELERATOR_ALIGN(EAG(mem)); 
     173                EAG(mem) += sizeof(zend_internal_function); 
     174        } else if (from->type == ZEND_USER_FUNCTION) { 
     175                EACCELERATOR_ALIGN(EAG(mem)); 
     176                EAG(mem) += sizeof(eaccelerator_op_array); 
     177        } else { 
     178                ea_debug_error("[%d] EACCELERATOR can't cache function \"%s\"\n", getpid(), from->function_name); 
     179                zend_bailout(); 
     180        } 
     181#ifdef ZEND_ENGINE_2 
     182        if (from->num_args > 0) { 
     183                zend_uint i; 
     184                EACCELERATOR_ALIGN(EAG(mem)); 
     185                EAG(mem) += from->num_args * sizeof(zend_arg_info); 
     186                for (i = 0; i < from->num_args; i++) { 
     187                        if (from->arg_info[i].name) 
     188                                calc_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); 
     189                        if (from->arg_info[i].class_name) 
     190                                calc_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
     191                } 
     192        } 
    203193#else 
    204     if (from->arg_types != NULL) { 
    205         calc_string ((char *) from->arg_types, 
    206                      (from->arg_types[0] + 1) * sizeof (zend_uchar) TSRMLS_CC); 
    207     } 
    208 #endif 
    209     if (from->function_name != NULL) { 
    210         calc_string (from->function_name, 
    211                      strlen (from->function_name) + 1 TSRMLS_CC); 
    212     } 
    213 #ifdef ZEND_ENGINE_2 
    214     if (from->scope != NULL) { 
    215         // HOESH: the same problem? 
    216         Bucket *q = CG (class_table)->pListHead; 
    217         while (q != NULL) { 
    218             if (*(zend_class_entry **) q->pData == from->scope) { 
    219                 calc_string (q->arKey, q->nKeyLength TSRMLS_CC); 
    220                 break; 
    221             } 
    222             q = q->pListNext; 
    223         } 
    224     } 
    225 #endif 
    226     if (from->type == ZEND_INTERNAL_FUNCTION) { 
    227         return; 
    228     } 
    229  
    230     if (from->opcodes != NULL) { 
    231         EACCELERATOR_ALIGN (EAG (mem)); 
    232         EAG (mem) += from->last * sizeof (zend_op); 
    233  
    234         opline = from->opcodes; 
    235         end = opline + from->last; 
    236         EAG (compress) = 0; 
    237         for (; opline < end; opline++) { 
     194        if (from->arg_types != NULL) 
     195                calc_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); 
     196#endif 
     197        if (from->function_name != NULL) 
     198                calc_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); 
     199#ifdef ZEND_ENGINE_2 
     200        if (from->scope != NULL) { 
     201                // HOESH: the same problem? 
     202                Bucket *q = CG(class_table)->pListHead; 
     203                while (q != NULL) { 
     204                        if (*(zend_class_entry **) q->pData == from->scope) { 
     205                                calc_string(q->arKey, q->nKeyLength TSRMLS_CC); 
     206                                break; 
     207                        } 
     208                        q = q->pListNext; 
     209                } 
     210        } 
     211#endif 
     212        if (from->type == ZEND_INTERNAL_FUNCTION) 
     213                return; 
     214 
     215        if (from->opcodes != NULL) { 
     216                EACCELERATOR_ALIGN(EAG(mem)); 
     217                EAG(mem) += from->last * sizeof(zend_op); 
     218 
     219                opline = from->opcodes; 
     220                end = opline + from->last; 
     221                EAG(compress) = 0; 
     222                for (; opline < end; opline++) { 
    238223/* 
    239224      if (opline->result.op_type == IS_CONST) calc_zval(&opline->result.u.constant  TSRMLS_CC); 
    240225*/ 
    241             if (opline->op1.op_type == IS_CONST) 
    242                 calc_zval (&opline->op1.u.constant TSRMLS_CC); 
    243             if (opline->op2.op_type == IS_CONST) 
    244                 calc_zval (&opline->op2.u.constant TSRMLS_CC); 
    245         } 
    246         EAG (compress) = 1; 
    247     } 
    248     if (from->brk_cont_array != NULL) { 
    249         EACCELERATOR_ALIGN (EAG (mem)); 
    250         EAG (mem) += sizeof (zend_brk_cont_element) * from->last_brk_cont; 
    251     } 
    252 #ifdef ZEND_ENGINE_2 
    253     /* HOESH: try & catch support */ 
    254     if (from->try_catch_array != NULL) { 
    255         EACCELERATOR_ALIGN (EAG (mem)); 
    256         EAG (mem) += sizeof (zend_try_catch_element) * from->last_try_catch; 
    257     } 
    258 #endif 
    259     if (from->static_variables != NULL) { 
    260         EACCELERATOR_ALIGN (EAG (mem)); 
    261         EAG (mem) += sizeof (HashTable); 
    262         calc_zval_hash (from->static_variables); 
    263     } 
    264     if (from->filename != NULL) { 
    265         calc_string (from->filename, strlen (from->filename) + 1 TSRMLS_CC); 
    266     } 
    267 #ifdef ZEND_ENGINE_2 
    268     if (from->doc_comment != NULL) { 
    269         calc_string (from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); 
    270     } 
     226                        if (opline->op1.op_type == IS_CONST) 
     227                                calc_zval(&opline->op1.u.constant TSRMLS_CC); 
     228                        if (opline->op2.op_type == IS_CONST) 
     229                                calc_zval(&opline->op2.u.constant TSRMLS_CC); 
     230                } 
     231                EAG(compress) = 1; 
     232        } 
     233        if (from->brk_cont_array != NULL) { 
     234                EACCELERATOR_ALIGN(EAG(mem)); 
     235                EAG(mem) += sizeof(zend_brk_cont_element) * from->last_brk_cont; 
     236        } 
     237#ifdef ZEND_ENGINE_2 
     238        /* HOESH: try & catch support */ 
     239        if (from->try_catch_array != NULL) { 
     240                EACCELERATOR_ALIGN(EAG(mem)); 
     241                EAG(mem) += sizeof(zend_try_catch_element) * from->last_try_catch; 
     242        } 
     243#endif 
     244        if (from->static_variables != NULL) { 
     245                EACCELERATOR_ALIGN(EAG(mem)); 
     246                EAG(mem) += sizeof(HashTable); 
     247                calc_zval_hash(from->static_variables); 
     248        } 
     249        if (from->filename != NULL) 
     250                calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     251#ifdef ZEND_ENGINE_2 
     252        if (from->doc_comment != NULL) 
     253                calc_string(from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); 
    271254#endif 
    272255} 
    273256 
    274257/* Calculate the size of a class entry */ 
    275 void calc_class_entry (zend_class_entry * from TSRMLS_DC) 
    276 
    277     if (from->type != ZEND_USER_CLASS) { 
    278         ea_debug_error ("[%d] EACCELERATOR can't cache internal class \"%s\"\n", 
    279                         getpid (), from->name); 
    280         zend_bailout (); 
    281     } 
    282     EACCELERATOR_ALIGN (EAG (mem)); 
    283     EAG (mem) += sizeof (eaccelerator_class_entry); 
    284  
    285     if (from->name != NULL) { 
    286         calc_string (from->name, from->name_length + 1 TSRMLS_CC); 
    287     } 
    288     if (from->parent != NULL && from->parent->name) { 
    289         calc_string (from->parent->name, 
    290                      from->parent->name_length + 1 TSRMLS_CC); 
    291     } 
     258void calc_class_entry(zend_class_entry * from TSRMLS_DC) 
     259
     260        if (from->type != ZEND_USER_CLASS) { 
     261                ea_debug_error("[%d] EACCELERATOR can't cache internal class \"%s\"\n", getpid(), from->name); 
     262                zend_bailout(); 
     263        } 
     264        EACCELERATOR_ALIGN(EAG(mem)); 
     265        EAG(mem) += sizeof(eaccelerator_class_entry); 
     266 
     267        if (from->name != NULL) 
     268                calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
     269        if (from->parent != NULL && from->parent->name) 
     270                calc_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 
    292271#ifdef ZEND_ENGINE_2 
    293272#if 0 
    294     // what's problem. why from->interfaces[i] == 0x5a5a5a5a ? 
    295     for (i = 0; i < from->num_interfaces; i++) { 
    296         if (from->interfaces[i]) { 
    297             calc_string (from->interfaces[i]->name, 
    298                          from->interfaces[i]->name_length); 
    299         } 
    300     } 
    301 #endif 
    302     if (from->filename != NULL) { 
    303         calc_string (from->filename, strlen (from->filename) + 1 TSRMLS_CC); 
    304     } 
    305     if (from->doc_comment != NULL) { 
    306         calc_string (from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); 
    307     } 
    308  
    309     calc_zval_hash (&from->constants_table); 
    310     calc_zval_hash (&from->default_properties); 
    311     calc_hash (&from->properties_info, (calc_bucket_t) calc_property_info); 
    312     if (from->static_members != NULL) { 
    313         EACCELERATOR_ALIGN (EAG (mem)); 
    314         EAG (mem) += sizeof (HashTable); 
    315         calc_zval_hash (from->static_members); 
    316     } 
     273        // what's problem. why from->interfaces[i] == 0x5a5a5a5a ? 
     274        for (i = 0; i < from->num_interfaces; i++) { 
     275                if (from->interfaces[i]) { 
     276                        calc_string(from->interfaces[i]->name, 
     277                                                from->interfaces[i]->name_length); 
     278                } 
     279        } 
     280#endif 
     281        if (from->filename != NULL) 
     282                calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     283        if (from->doc_comment != NULL) 
     284                calc_string(from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); 
     285 
     286        calc_zval_hash(&from->constants_table); 
     287        calc_zval_hash(&from->default_properties); 
     288        calc_hash(&from->properties_info, (calc_bucket_t) calc_property_info); 
     289        if (from->static_members != NULL) { 
     290                EACCELERATOR_ALIGN(EAG(mem)); 
     291                EAG(mem) += sizeof(HashTable); 
     292                calc_zval_hash(from->static_members); 
     293        } 
    317294#else 
    318     calc_zval_hash (&from->default_properties); 
    319 #endif 
    320     calc_hash (&from->function_table, (calc_bucket_t) calc_op_array); 
     295       calc_zval_hash(&from->default_properties); 
     296#endif 
     297       calc_hash(&from->function_table, (calc_bucket_t) calc_op_array); 
    321298} 
    322299 
    323300/* Calculate the size of a cache entry with its given op_array and function and 
    324301   class bucket */ 
    325 int calc_size (char *key, zend_op_array * op_array, 
    326                Bucket * f, Bucket * c TSRMLS_DC) 
    327 
    328     Bucket *b; 
    329     char *x; 
    330     int len = strlen (key); 
    331     EAG (compress) = 1; 
    332     EAG (mem) = NULL; 
    333  
    334     zend_hash_init (&EAG (strings), 0, NULL, NULL, 0); 
    335     EAG (mem) += offsetof (mm_cache_entry, realfilename) + len + 1; 
    336     zend_hash_add (&EAG (strings), key, len + 1, &key, sizeof (char *), NULL); 
    337     b = c; 
    338     while (b != NULL) { 
    339         EACCELERATOR_ALIGN (EAG (mem)); 
    340         EAG (mem) += offsetof (mm_fc_entry, htabkey) + b->nKeyLength; 
    341         x = b->arKey; 
    342         zend_hash_add (&EAG (strings), b->arKey, b->nKeyLength, &x, 
    343                        sizeof (char *), NULL); 
    344         b = b->pListNext; 
    345     } 
    346     b = f; 
    347     while (b != NULL) { 
    348         EACCELERATOR_ALIGN (EAG (mem)); 
    349         EAG (mem) += offsetof (mm_fc_entry, htabkey) + b->nKeyLength; 
    350         x = b->arKey; 
    351         zend_hash_add (&EAG (strings), b->arKey, b->nKeyLength, &x, 
    352                        sizeof (char *), NULL); 
    353         b = b->pListNext; 
    354     } 
    355     while (c != NULL) { 
    356 #ifdef ZEND_ENGINE_2 
    357         calc_class_entry (*(zend_class_entry **) c->pData TSRMLS_CC); 
     302int calc_size(char *key, zend_op_array * op_array, 
     303                          Bucket * f, Bucket * c TSRMLS_DC) 
     304
     305        Bucket *b; 
     306        char *x; 
     307        int len = strlen(key); 
     308        EAG(compress) = 1; 
     309        EAG(mem) = NULL; 
     310 
     311        zend_hash_init(&EAG(strings), 0, NULL, NULL, 0); 
     312        EAG(mem) += offsetof(mm_cache_entry, realfilename) + len + 1; 
     313        zend_hash_add(&EAG(strings), key, len + 1, &key, sizeof(char *), NULL); 
     314        b = c; 
     315        while (b != NULL) { 
     316                EACCELERATOR_ALIGN(EAG(mem)); 
     317                EAG(mem) += offsetof(mm_fc_entry, htabkey) + b->nKeyLength; 
     318                x = b->arKey; 
     319                zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); 
     320                b = b->pListNext; 
     321        } 
     322        b = f; 
     323        while (b != NULL) { 
     324                EACCELERATOR_ALIGN(EAG(mem)); 
     325                EAG(mem) += offsetof(mm_fc_entry, htabkey) + b->nKeyLength; 
     326                x = b->arKey; 
     327                zend_hash_add(&EAG(strings), b->arKey, b->nKeyLength, &x, sizeof(char *), NULL); 
     328                b = b->pListNext; 
     329        } 
     330        while (c != NULL) { 
     331#ifdef ZEND_ENGINE_2 
     332                calc_class_entry(*(zend_class_entry **) c->pData TSRMLS_CC); 
    358333#else 
    359         calc_class_entry ((zend_class_entry *) c->pData TSRMLS_CC); 
    360 #endif 
    361         c = c->pListNext; 
    362    
    363     while (f != NULL) { 
    364         calc_op_array ((zend_op_array *) f->pData TSRMLS_CC); 
    365         f = f->pListNext; 
    366    
    367     calc_op_array (op_array TSRMLS_CC); 
    368     EACCELERATOR_ALIGN (EAG (mem)); 
    369     zend_hash_destroy (&EAG (strings)); 
    370     return (size_t) EAG (mem); 
     334               calc_class_entry((zend_class_entry *) c->pData TSRMLS_CC); 
     335#endif 
     336               c = c->pListNext; 
     337       
     338       while (f != NULL) { 
     339               calc_op_array((zend_op_array *) f->pData TSRMLS_CC); 
     340               f = f->pListNext; 
     341       
     342       calc_op_array(op_array TSRMLS_CC); 
     343       EACCELERATOR_ALIGN(EAG(mem)); 
     344       zend_hash_destroy(&EAG(strings)); 
     345       return (size_t) EAG(mem); 
    371346} 
    372347 
    373348/** Functions to store a script **/ 
    374 static inline char *store_string (char *str, int len TSRMLS_DC) 
    375 
    376     char *p; 
    377     if (len > MAX_DUP_STR_LEN) { 
    378         EACCELERATOR_ALIGN (EAG (mem)); 
    379         p = (char *) EAG (mem); 
    380         EAG (mem) += len; 
    381         memcpy (p, str, len); 
    382     } else if (zend_hash_find (&EAG (strings), str, len, (void *) &p) == 
    383                SUCCESS) { 
    384         p = *(char **) p; 
    385     } else { 
    386         EACCELERATOR_ALIGN (EAG (mem)); 
    387         p = (char *) EAG (mem); 
    388         EAG (mem) += len; 
    389         memcpy (p, str, len); 
    390         zend_hash_add (&EAG (strings), str, len, (void *) &p, sizeof (char *), 
    391                        NULL); 
    392     } 
    393     return p; 
     349static inline char *store_string(char *str, int len TSRMLS_DC) 
     350
     351        char *p; 
     352        if (len > MAX_DUP_STR_LEN) { 
     353                EACCELERATOR_ALIGN(EAG(mem)); 
     354                p = (char *) EAG(mem); 
     355                EAG(mem) += len; 
     356                memcpy(p, str, len); 
     357        } else if (zend_hash_find(&EAG(strings), str, len, (void *) &p) == SUCCESS) { 
     358                p = *(char **) p; 
     359        } else { 
     360                EACCELERATOR_ALIGN(EAG(mem)); 
     361                p = (char *) EAG(mem); 
     362                EAG(mem) += len; 
     363                memcpy(p, str, len); 
     364                zend_hash_add(&EAG(strings), str, len, (void *) &p, sizeof(char *), NULL); 
     365        } 
     366        return p; 
    394367} 
    395368 
     
    408381  store_hash_ex(to, from, start, (store_bucket_t)store_zval_ptr) 
    409382 
    410 static zval *store_zval_ptr (zval * from TSRMLS_DC) 
    411 
    412     zval *to; 
    413     EACCELERATOR_ALIGN (EAG (mem)); 
    414     to = (zval *) EAG (mem); 
    415     EAG (mem) += sizeof (zval); 
    416     memcpy (to, from, sizeof (zval)); 
    417     store_zval (to TSRMLS_CC); 
    418     return to; 
    419 
    420  
    421 static void store_hash_int (HashTable * target, HashTable * source, 
    422                             Bucket * start, 
    423                             store_bucket_t copy_bucket TSRMLS_DC) 
    424 
    425     Bucket *p, *np, *prev_p; 
    426  
    427     memcpy (target, source, sizeof (HashTable)); 
    428  
    429     if (source->nNumOfElements > 0) { 
    430         if (!EAG (compress)) { 
    431             EACCELERATOR_ALIGN (EAG (mem)); 
    432             target->arBuckets = (Bucket **) EAG (mem); 
    433             EAG (mem) += target->nTableSize * sizeof (Bucket *); 
    434             memset (target->arBuckets, 0, 
    435                     target->nTableSize * sizeof (Bucket *)); 
    436         } 
    437  
    438         target->pDestructor = NULL; 
    439         target->persistent = 1; 
    440         target->pListHead = NULL; 
    441         target->pListTail = NULL; 
    442  
    443         p = start; 
    444         prev_p = NULL; 
    445         np = NULL; 
    446         while (p) { 
    447             EACCELERATOR_ALIGN (EAG (mem)); 
    448             np = (Bucket *) EAG (mem); 
    449             EAG (mem) += offsetof (Bucket, arKey) + p->nKeyLength; 
    450  
    451             if (!EAG (compress)) { 
    452                 int nIndex = p->h % source->nTableSize; 
    453                 if (target->arBuckets[nIndex]) { 
    454                     np->pNext = target->arBuckets[nIndex]; 
    455                     np->pLast = NULL; 
    456                     np->pNext->pLast = np; 
    457                 } else { 
    458                     np->pNext = NULL; 
    459                     np->pLast = NULL; 
    460                 } 
    461                 target->arBuckets[nIndex] = np; 
    462             } 
    463             np->h = p->h; 
    464             np->nKeyLength = p->nKeyLength; 
    465  
    466             if (p->pDataPtr == NULL) { 
    467                 np->pData = copy_bucket (p->pData TSRMLS_CC); 
    468                 np->pDataPtr = NULL; 
    469             } else { 
    470                 np->pDataPtr = copy_bucket (p->pDataPtr TSRMLS_CC); 
    471                 np->pData = &np->pDataPtr; 
    472             } 
    473  
    474             np->pListLast = prev_p; 
    475             np->pListNext = NULL; 
    476  
    477             memcpy (np->arKey, p->arKey, p->nKeyLength); 
    478  
    479             if (prev_p) { 
    480                 prev_p->pListNext = np; 
    481             } else { 
    482                 target->pListHead = np; 
    483             } 
    484             prev_p = np; 
    485             p = p->pListNext; 
    486         } 
    487         target->pListTail = np; 
    488         target->pInternalPointer = target->pListHead; 
     383static zval *store_zval_ptr(zval * from TSRMLS_DC) 
     384
     385        zval *to; 
     386        EACCELERATOR_ALIGN(EAG(mem)); 
     387        to = (zval *) EAG(mem); 
     388        EAG(mem) += sizeof(zval); 
     389        memcpy(to, from, sizeof(zval)); 
     390        store_zval(to TSRMLS_CC); 
     391        return to; 
     392
     393 
     394static void store_hash_int(HashTable * target, HashTable * source, 
     395                                                   Bucket * start, store_bucket_t copy_bucket TSRMLS_DC) 
     396
     397        Bucket *p, *np, *prev_p; 
     398 
     399        memcpy(target, source, sizeof(HashTable)); 
     400 
     401        if (source->nNumOfElements > 0) { 
     402                if (!EAG(compress)) { 
     403                        EACCELERATOR_ALIGN(EAG(mem)); 
     404                        target->arBuckets = (Bucket **) EAG(mem); 
     405                        EAG(mem) += target->nTableSize * sizeof(Bucket *); 
     406                        memset(target->arBuckets, 0, target->nTableSize * sizeof(Bucket *)); 
     407                } 
     408 
     409                target->pDestructor = NULL; 
     410                target->persistent = 1; 
     411                target->pListHead = NULL; 
     412                target->pListTail = NULL; 
     413 
     414                p = start; 
     415                prev_p = NULL; 
     416                np = NULL; 
     417                while (p) { 
     418                        EACCELERATOR_ALIGN(EAG(mem)); 
     419                        np = (Bucket *) EAG(mem); 
     420                        EAG(mem) += offsetof(Bucket, arKey) + p->nKeyLength; 
     421 
     422                        if (!EAG(compress)) { 
     423                                int nIndex = p->h % source->nTableSize; 
     424                                if (target->arBuckets[nIndex]) { 
     425                                        np->pNext = target->arBuckets[nIndex]; 
     426                                        np->pLast = NULL; 
     427                                        np->pNext->pLast = np; 
     428                                } else { 
     429                                        np->pNext = NULL; 
     430                                        np->pLast = NULL; 
     431                                } 
     432                                target->arBuckets[nIndex] = np; 
     433                        } 
     434                        np->h = p->h; 
     435                        np->nKeyLength = p->nKeyLength; 
     436 
     437                        if (p->pDataPtr == NULL) { 
     438                                np->pData = copy_bucket(p->pData TSRMLS_CC); 
     439                                np->pDataPtr = NULL; 
     440                        } else { 
     441                                np->pDataPtr = copy_bucket(p->pDataPtr TSRMLS_CC); 
     442                                np->pData = &np->pDataPtr; 
     443                        } 
     444 
     445                        np->pListLast = prev_p; 
     446                        np->pListNext = NULL; 
     447 
     448                        memcpy(np->arKey, p->arKey, p->nKeyLength); 
     449 
     450                        if (prev_p) { 
     451                                prev_p->pListNext = np; 
     452                        } else { 
     453                                target->pListHead = np; 
     454                        } 
     455                        prev_p = np; 
     456                        p = p->pListNext; 
     457                } 
     458                target->pListTail = np; 
     459                target->pInternalPointer = target->pListHead; 
     460        } 
     461
     462 
     463void store_zval(zval * zv TSRMLS_DC) 
     464
     465        switch (zv->type & ~IS_CONSTANT_INDEX) { 
     466        case IS_CONSTANT: 
     467        case IS_STRING: 
     468                if (zv->value.str.val == NULL || 
     469                        zv->value.str.val == empty_string || zv->value.str.len == 0) { 
     470                        zv->value.str.val = empty_string; 
     471                        zv->value.str.len = 0; 
     472                } else { 
     473                        zv->value.str.val = store_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); 
     474                } 
     475                break; 
     476        case IS_ARRAY: 
     477        case IS_CONSTANT_ARRAY: 
     478                if (zv->value.ht != NULL && zv->value.ht != &EG(symbol_table)) { 
     479                        HashTable *p; 
     480                        EACCELERATOR_ALIGN(EAG(mem)); 
     481                        p = (HashTable *) EAG(mem); 
     482                        EAG(mem) += sizeof(HashTable); 
     483                        store_zval_hash(p, zv->value.ht); 
     484                        zv->value.ht = p; 
     485                } 
     486                break; 
     487        case IS_OBJECT: 
     488                if (!EAG(compress)) { 
     489                        return; 
     490                } 
     491#ifndef ZEND_ENGINE_2 
     492                if (zv->value.obj.ce != NULL) { 
     493                        char *s = store_string(zv->value.obj.ce->name, zv->value.obj.ce->name_length + 1 TSRMLS_CC); 
     494                        zend_str_tolower(s, zv->value.obj.ce->name_length); 
     495                        zv->value.obj.ce = (zend_class_entry *) s; 
     496                } 
     497                if (zv->value.obj.properties != NULL) { 
     498                        HashTable *p; 
     499                        EACCELERATOR_ALIGN(EAG(mem)); 
     500                        p = (HashTable *) EAG(mem); 
     501                        EAG(mem) += sizeof(HashTable); 
     502                        store_zval_hash(p, zv->value.obj.properties); 
     503                        zv->value.obj.properties = p; 
     504                } 
     505#endif 
     506        default: 
     507                break; 
     508        } 
     509
     510 
     511eaccelerator_op_array *store_op_array(zend_op_array * from TSRMLS_DC) 
     512
     513        eaccelerator_op_array *to; 
     514        zend_op *opline; 
     515        zend_op *end; 
     516 
     517        ea_debug_pad(EA_DEBUG TSRMLS_CC); 
     518        ea_debug_printf(EA_DEBUG, "[%d] store_op_array: %s [scope=%s]\n",  
     519            getpid(), from->function_name ? from->function_name : "(top)", 
     520#ifdef ZEND_ENGINE_2 
     521                        from->scope ? from->scope->name : "NULL" 
     522#else 
     523                        "NULL" 
     524#endif 
     525                ); 
     526 
     527        if (from->type == ZEND_INTERNAL_FUNCTION) { 
     528                EACCELERATOR_ALIGN(EAG(mem)); 
     529                to = (eaccelerator_op_array *) EAG(mem); 
     530                EAG(mem) += offsetof(eaccelerator_op_array, opcodes); 
     531        } else if (from->type == ZEND_USER_FUNCTION) { 
     532                EACCELERATOR_ALIGN(EAG(mem)); 
     533                to = (eaccelerator_op_array *) EAG(mem); 
     534                EAG(mem) += sizeof(eaccelerator_op_array); 
     535        } else { 
     536                return NULL; 
     537        } 
     538 
     539        to->type = from->type; 
     540#ifdef ZEND_ENGINE_2 
     541        to->num_args = from->num_args; 
     542        to->required_num_args = from->required_num_args; 
     543        if (from->num_args > 0) { 
     544                zend_uint i; 
     545                EACCELERATOR_ALIGN(EAG(mem)); 
     546                to->arg_info = (zend_arg_info *) EAG(mem); 
     547                EAG(mem) += from->num_args * sizeof(zend_arg_info); 
     548                for (i = 0; i < from->num_args; i++) { 
     549                        if (from->arg_info[i].name) { 
     550                                to->arg_info[i].name = store_string(from->arg_info[i].name, from->arg_info[i].name_len + 1 TSRMLS_CC); 
     551                                to->arg_info[i].name_len = from->arg_info[i].name_len; 
     552                        } 
     553                        if (from->arg_info[i].class_name) { 
     554                                to->arg_info[i].class_name = store_string(from->arg_info[i].class_name, from->arg_info[i].class_name_len + 1 TSRMLS_CC); 
     555                                to->arg_info[i].class_name_len = from->arg_info[i].class_name_len; 
     556                        } 
     557                        to->arg_info[i].allow_null = from->arg_info[i].allow_null; 
     558                        to->arg_info[i].pass_by_reference = from->arg_info[i].pass_by_reference; 
     559                        to->arg_info[i].return_reference = from->arg_info[i].return_reference; 
     560                } 
     561        } 
     562        to->pass_rest_by_reference = from->pass_rest_by_reference; 
     563#else 
     564        if (from->arg_types != NULL) 
     565                to->arg_types = (unsigned char *) store_string((char *) from->arg_types, (from->arg_types[0] + 1) * sizeof(zend_uchar) TSRMLS_CC); 
     566#endif 
     567        if (from->function_name != NULL) 
     568                to->function_name = store_string(from->function_name, strlen(from->function_name) + 1 TSRMLS_CC); 
     569#ifdef ZEND_ENGINE_2 
     570        to->fn_flags = from->fn_flags; 
     571        to->scope_name = NULL; 
     572        to->scope_name_len = 0; 
     573        if (from->scope != NULL) { 
     574                Bucket *q = CG(class_table)->pListHead; 
     575                while (q != NULL) { 
     576                        if (*(zend_class_entry **) q->pData == from->scope) { 
     577                                to->scope_name = store_string(q->arKey, q->nKeyLength TSRMLS_CC); 
     578                                to->scope_name_len = q->nKeyLength - 1; 
     579 
     580                                ea_debug_pad(EA_DEBUG TSRMLS_CC); 
     581                                ea_debug_printf(EA_DEBUG,  
     582                        "[%d]                 find scope '%s' in CG(class_table) save hashkey '%s' [%08x] as to->scope_name\n", 
     583                                                getpid(), from->scope->name ? from->scope->name : "NULL", q->arKey, to->scope_name); 
     584                                break; 
     585                        } 
     586                        q = q->pListNext; 
     587                } 
     588            if (to->scope_name == NULL) { 
     589                    ea_debug_pad(EA_DEBUG TSRMLS_CC); 
     590                    ea_debug_printf(EA_DEBUG, 
     591                                                "[%d]                 could not find scope '%s' in CG(class_table), saving it to NULL\n", 
     592                                                getpid(), from->scope->name ? from->scope->name : "NULL"); 
     593            } 
    489594    } 
    490 
    491  
    492 void store_zval (zval * zv TSRMLS_DC) 
    493 
    494     switch (zv->type & ~IS_CONSTANT_INDEX) { 
    495     case IS_CONSTANT: 
    496     case IS_STRING: 
    497         if (zv->value.str.val == NULL || 
    498             zv->value.str.val == empty_string || zv->value.str.len == 0) { 
    499             zv->value.str.val = empty_string; 
    500             zv->value.str.len = 0; 
    501         } else { 
    502             zv->value.str.val = 
    503                 store_string (zv->value.str.val, 
    504                               zv->value.str.len + 1 TSRMLS_CC); 
    505         } 
    506         break; 
    507     case IS_ARRAY: 
    508     case IS_CONSTANT_ARRAY: 
    509         if (zv->value.ht == NULL || zv->value.ht == &EG (symbol_table)) { 
    510         } else { 
    511             HashTable *p; 
    512             EACCELERATOR_ALIGN (EAG (mem)); 
    513             p = (HashTable *) EAG (mem); 
    514             EAG (mem) += sizeof (HashTable); 
    515             store_zval_hash (p, zv->value.ht); 
    516             zv->value.ht = p; 
    517         } 
    518         break; 
    519     case IS_OBJECT: 
    520         if (!EAG (compress)) { 
    521             return; 
    522         } 
    523 #ifndef ZEND_ENGINE_2 
    524         if (zv->value.obj.ce != NULL) { 
    525             char *s = store_string (zv->value.obj.ce->name, 
    526                                     zv->value.obj.ce->name_length + 
    527                                     1 TSRMLS_CC); 
    528             zend_str_tolower (s, zv->value.obj.ce->name_length); 
    529             zv->value.obj.ce = (zend_class_entry *) s; 
    530         } 
    531         if (zv->value.obj.properties != NULL) { 
    532             HashTable *p; 
    533             EACCELERATOR_ALIGN (EAG (mem)); 
    534             p = (HashTable *) EAG (mem); 
    535             EAG (mem) += sizeof (HashTable); 
    536             store_zval_hash (p, zv->value.obj.properties); 
    537             zv->value.obj.properties = p; 
    538         } 
    539 #endif 
    540     default: 
    541   &n