Show
Ignore:
Timestamp:
02/17/06 18:35:50 (3 years ago)
Author:
zoeloelip
Message:

Merged PHP_5_1 branch with HEAD

Files:

Legend:

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

    r124 r162  
    8383        EAG(mem) += sizeof(zend_property_info); 
    8484        calc_string(from->name, from->name_length + 1 TSRMLS_CC); 
     85#ifdef ZEND_ENGINE_2_1 
     86        if (from->doc_comment != NULL) { 
     87                calc_string(from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); 
     88        } 
     89#endif 
    8590} 
    8691 
     
    118123        case IS_CONSTANT: 
    119124        case IS_STRING: 
    120                if (zv->value.str.val == NULL || zv->value.str.val == empty_string || zv->value.str.len == 0) { 
    121                 } else { 
     125/*             if (zv->value.str.val == NULL || zv->value.str.len == 0) { 
     126                } else {*/ 
    122127                        calc_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); 
    123                 } 
     128/*              }*/ 
    124129                break; 
    125130        case IS_ARRAY: 
     
    247252                calc_zval_hash(from->static_variables); 
    248253        } 
     254#ifdef ZEND_ENGINE_2_1 
     255        if (from->vars != NULL) { 
     256                zend_uint i; 
     257                EACCELERATOR_ALIGN(EAG(mem)); 
     258                EAG(mem) += sizeof(zend_compiled_variable) * from->last_var; 
     259                for (i = 0; i < from->last_var; i ++) { 
     260                        calc_string(from->vars[i].name, from->vars[i].name_len+1 TSRMLS_CC); 
     261                } 
     262        } 
     263#endif 
    249264        if (from->filename != NULL) 
    250265                calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     
    270285                calc_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 
    271286#ifdef ZEND_ENGINE_2 
    272 #if 0 
    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 
    281287        if (from->filename != NULL) 
    282288                calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     
    286292        calc_zval_hash(&from->constants_table); 
    287293        calc_zval_hash(&from->default_properties); 
     294 
    288295        calc_hash(&from->properties_info, (calc_bucket_t) calc_property_info); 
     296 
     297#  ifdef ZEND_ENGINE_2_1 
     298        calc_zval_hash(&from->default_static_members); 
     299        if ((from->static_members != NULL) && (from->static_members != &from->default_static_members)) { 
     300#  else 
    289301        if (from->static_members != NULL) { 
     302#  endif 
    290303                EACCELERATOR_ALIGN(EAG(mem)); 
    291304                EAG(mem) += sizeof(HashTable); 
     
    368381 
    369382typedef void *(*store_bucket_t) (void *TSRMLS_DC); 
    370  
    371 #define store_hash_ex(to, from, start, store_bucket) \ 
    372   store_hash_int(to, from, start, store_bucket TSRMLS_CC) 
    373  
    374 #define store_hash(to, from, store_bucket) \ 
    375   store_hash_ex(to, from, (from)->pListHead, store_bucket) 
     383typedef void *(*check_bucket_t) (Bucket*, va_list); 
     384 
     385#define store_hash_ex(to, from, start, store_bucket, check_bucket, ...) \ 
     386  store_hash_int(to, from, start, store_bucket, check_bucket, __VA_ARGS__) 
     387 
     388#define store_hash(to, from, store_bucket, check_bucket, ...) \ 
     389  store_hash_ex(to, from, (from)->pListHead, store_bucket, check_bucket, __VA_ARGS__) 
    376390 
    377391#define store_zval_hash(to, from) \ 
    378   store_hash(to, from, (store_bucket_t)store_zval_ptr
     392  store_hash(to, from, (store_bucket_t)store_zval_ptr, NULL, NULL
    379393 
    380394#define store_zval_hash_ex(to, from, start) \ 
    381   store_hash_ex(to, from, start, (store_bucket_t)store_zval_ptr
     395  store_hash_ex(to, from, start, (store_bucket_t)store_zval_ptr, NULL
    382396 
    383397static zval *store_zval_ptr(zval * from TSRMLS_DC) 
     
    393407 
    394408static void store_hash_int(HashTable * target, HashTable * source, 
    395                                                    Bucket * start, store_bucket_t copy_bucket TSRMLS_DC) 
     409                                                   Bucket * start, store_bucket_t copy_bucket, 
     410                                                                   check_bucket_t check_bucket, ...) 
    396411{ 
    397412        Bucket *p, *np, *prev_p; 
     413        TSRMLS_FETCH(); 
    398414 
    399415        memcpy(target, source, sizeof(HashTable)); 
     
    416432                np = NULL; 
    417433                while (p) { 
     434                        /* If a check function has been defined, run it */ 
     435                        if (check_bucket) { 
     436                                va_list args; 
     437                                va_start(args, check_bucket); 
     438 
     439                                /* If the check function returns ZEND_HASH_APPLY_REMOVE, don't store this record, skip over it */ 
     440                                if(check_bucket(p, args)) { 
     441                                        p = p->pListNext; 
     442                                        target->nNumOfElements--; 
     443                                        /* skip to next itteration */ 
     444                                        continue; 
     445                                } 
     446                                va_end(args); 
     447                        } 
     448 
    418449                        EACCELERATOR_ALIGN(EAG(mem)); 
    419450                        np = (Bucket *) EAG(mem); 
     
    466497        case IS_CONSTANT: 
    467498        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                 } 
     499                zv->value.str.val = store_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); 
    475500                break; 
    476501        case IS_ARRAY: 
     
    516541 
    517542        ea_debug_pad(EA_DEBUG TSRMLS_CC); 
    518         ea_debug_printf(EA_DEBUG, "[%d] store_op_array: %s [scope=%s]\n",  
     543        ea_debug_printf(EA_DEBUG, "[%d] store_op_array: %s [scope=%s type=%x]\n",  
    519544            getpid(), from->function_name ? from->function_name : "(top)", 
    520545#ifdef ZEND_ENGINE_2 
     
    523548                        "NULL" 
    524549#endif 
     550                        , from->type 
    525551                ); 
    526552 
     
    555581                                to->arg_info[i].class_name_len = from->arg_info[i].class_name_len; 
    556582                        } 
     583#  ifdef ZEND_ENGINE_2_1 
     584                        /* php 5.1 introduces this in zend_arg_info for array type hinting */ 
     585                        to->arg_info[i].array_type_hint = from->arg_info[i].array_type_hint; 
     586#  endif 
    557587                        to->arg_info[i].allow_null = from->arg_info[i].allow_null; 
    558588                        to->arg_info[i].pass_by_reference = from->arg_info[i].pass_by_reference; 
     
    595625#endif 
    596626 
    597         if (from->type == ZEND_INTERNAL_FUNCTION) 
    598         return to; 
     627        if (from->type == ZEND_INTERNAL_FUNCTION) { 
     628#ifdef ZEND_ENGINE_2 
     629                /* zend_internal_function also contains return_reference in ZE2 */ 
     630                to->return_reference = from->return_reference; 
     631#endif           
     632                return to; 
     633        } 
    599634     
    600635        to->opcodes = from->opcodes; 
     
    672707                store_zval_hash(to->static_variables, from->static_variables); 
    673708        } 
     709#ifdef ZEND_ENGINE_2_1 
     710        if (from->vars != NULL) { 
     711                zend_uint i; 
     712                EACCELERATOR_ALIGN(EAG(mem)); 
     713                to->last_var = from->last_var; 
     714                to->vars = (zend_compiled_variable*)EAG(mem); 
     715                EAG(mem) += sizeof(zend_compiled_variable) * from->last_var; 
     716                        memcpy(to->vars, from->vars, sizeof(zend_compiled_variable) * from->last_var); 
     717                for (i = 0; i < from->last_var; i ++) { 
     718                        to->vars[i].name = store_string(from->vars[i].name, from->vars[i].name_len+1 TSRMLS_CC); 
     719                } 
     720        } else { 
     721                to->last_var = 0; 
     722                to->vars = NULL; 
     723        } 
     724#endif 
    674725        if (from->filename != NULL) { 
    675                 to->filename = store_string(to->filename, strlen(from->filename) + 1 TSRMLS_CC); 
     726                to->filename = store_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); 
    676727        } 
    677728#ifdef ZEND_ENGINE_2 
     
    694745        memcpy(to, from, sizeof(zend_property_info)); 
    695746        to->name = store_string(from->name, from->name_length + 1 TSRMLS_CC); 
     747#ifdef ZEND_ENGINE_2_1 
     748        to->doc_comment_len = from->doc_comment_len; 
     749        if (from->doc_comment != NULL) { 
     750                to->doc_comment = store_string(from->doc_comment, from->doc_comment_len + 1 TSRMLS_CC); 
     751        } 
     752#endif 
    696753        return to; 
    697754} 
    698 #endif 
     755 
     756/*  
     757 * The following two functions handle access checking of properties (public/private/protected)  
     758 * and control proper inheritance during copying of the properties_info and (default_)static_members hashes 
     759 * 
     760 * Both functions return ZEND_HASH_APPLY_REMOVE if the property to be copied needs to be skipped, or 
     761 * ZEND_HASH_APPLY_KEEP if the property needs to be copied over into the cache. 
     762 *   
     763 * If the property is skipped due to access restrictions, or it needs inheritance of its value from the 
     764 * parent, the restore phase will take care of that. 
     765 * 
     766 * Most of the logic behind all this can be found in zend_compile.c, functions zend_do_inheritance and 
     767 * zend_do_inherit_property_access_check 
     768*/ 
     769static int store_property_access_check(Bucket * p, va_list args) 
     770
     771        zend_class_entry *from = va_arg(args, zend_class_entry*); 
     772        zend_class_entry *parent = from->parent; 
     773         
     774        ea_debug_printf(EA_DEBUG, "[%d] store_property_access_check enter. from=%x parent=%x arKey=%s\n", getpid(), from, parent, p->arKey); 
     775         
     776        if (parent) { 
     777                // hra: TODO - do some usefull stuff :) 
     778                // check for ACC_PRIVATE etc. 
     779                // for now, just return keep 
     780        } 
     781        ea_debug_printf(EA_DEBUG, "[%d] store_property_access_check result: keep\n", getpid()); 
     782        return ZEND_HASH_APPLY_KEEP; 
     783
     784 
     785static int store_static_member_access_check(Bucket * p, va_list args) 
     786
     787        zend_class_entry *from = va_arg(args, zend_class_entry*); 
     788        zend_class_entry *parent = from->parent; 
     789        zend_property_info *pinfo, *cinfo = NULL; 
     790        zval **pprop = NULL; 
     791        zval **cprop = p->pData; 
     792        char *mname, *cname = NULL; 
     793 
     794        /* Check if this is a parent class. If so, copy unconditionally */ 
     795        if (parent) { 
     796                /* unpack the \0classname\0membername\0 style property name to seperate vars */ 
     797                zend_unmangle_property_name(p->arKey, &cname, &mname); 
     798                ea_debug_printf(EA_DEBUG, "[%d] store_static_member_access_check: cname=%s, mname=%s\n", getpid(), cname, mname); 
     799         
     800                /* lookup the member's info in parent and child */ 
     801                if((zend_hash_find(&parent->properties_info, mname, strlen(mname)+1, (void**)&pinfo) == SUCCESS) && 
     802                        (zend_hash_find(&from->properties_info, mname, strlen(mname)+1, (void**)&cinfo) == SUCCESS)) { 
     803                        /* don't copy this static property if protected in parent and static public in child. 
     804                           inheritance will handle this properly on restore */ 
     805                        if(cinfo->flags & ZEND_ACC_STATIC && (pinfo->flags & ZEND_ACC_PROTECTED && cinfo->flags & ZEND_ACC_PUBLIC)) { 
     806                                ea_debug_printf(EA_DEBUG, "[%d] store_static_member_access_check: child static public, parent protected, result: skip\n", getpid()); 
     807                                return ZEND_HASH_APPLY_REMOVE; 
     808                        } 
     809                        /* If the static member points to the same value in parent and child, remove for proper inheritance during restore */ 
     810#  ifdef ZEND_ENGINE_2_1 
     811                        if(zend_hash_quick_find(&parent->default_static_members, p->arKey, p->nKeyLength, p->h, (void**)&pprop) == SUCCESS) { 
     812#  else 
     813                        if(zend_hash_quick_find(&parent->static_members, p->arKey, p->nKeyLength, p->h, (void**)&pprop) == SUCCESS) { 
     814#  endif 
     815                                ea_debug_printf(EA_DEBUG, "[%d] store_static_member_access_check: SUCCESS looking up arKey\n",getpid()); 
     816                                ea_debug_printf(EA_DEBUG, "[%d] store_static_member_access_check: pprop=%x cprop=%x\n",getpid(), *pprop, *cprop); 
     817                                if(*pprop == *cprop) { 
     818                                        ea_debug_printf(EA_DEBUG, "[%d] store_static_member_access_check: pprop == cprop, result: skip\n",getpid()); 
     819                                        return ZEND_HASH_APPLY_REMOVE; 
     820                                } 
     821                        } 
     822                } 
     823        } 
     824        ea_debug_printf(EA_DEBUG, "[%d] store_static_member_access_check: result: keep\n",getpid()); 
     825        return ZEND_HASH_APPLY_KEEP; 
     826
     827#endif 
     828 
     829/* 
     830 * This function makes sure that functions/methods that are not in the scope of the current 
     831 * class being stored, do not get copied to the function_table hash. This makes sure they 
     832 * get properly inherited on restore by zend_do_inheritance 
     833 * 
     834 * If we dont do this, it will result in broken inheritance, problems with final methods 
     835 * (e.g. "Cannot override final method") and the like. 
     836 */ 
     837static int store_function_inheritance_check(Bucket * p, va_list args) 
     838
     839        zend_class_entry *from = va_arg(args, zend_class_entry*); 
     840        zend_function *zf = p->pData; 
     841         
     842        if (zf->common.scope == from) { 
     843                return ZEND_HASH_APPLY_KEEP; 
     844        } 
     845        return ZEND_HASH_APPLY_REMOVE; 
     846
    699847 
    700848eaccelerator_class_entry *store_class_entry(zend_class_entry * from TSRMLS_DC) 
     
    705853        EAG(mem) += sizeof(eaccelerator_class_entry); 
    706854        to->type = from->type; 
     855        ea_debug_printf(EA_DEBUG, "[%d] store_class_entry: class type=%d\n", getpid(), from->type); 
    707856        to->name = NULL; 
    708857        to->name_length = from->name_length; 
     
    712861        to->static_members = NULL; 
    713862        to->num_interfaces = from->num_interfaces; 
    714  
    715 #if 0 
    716         // i need to check more. why this field is null. 
    717         // 
    718         for (i = 0; i < from->num_interfaces; i++) { 
    719                 if (from->interfaces[i]) { 
    720                         to->interfaces[i] = 
    721                                 store_string(from->interfaces[i]->name, 
    722                                                          from->interfaces[i]->name_length); 
    723                 } 
    724         } 
    725 #endif 
    726  
     863        /* hrak: no need to really store the interfaces since these get populated 
     864         * at/after restore by zend_do_inheritance and ZEND_ADD_INTERFACE */ 
     865        to->interfaces = NULL; 
    727866#endif 
    728867 
     
    740879                to->parent = store_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 
    741880 
    742 /* 
    743   if (!from->constants_updated) { 
    744     zend_hash_apply_with_argument(&from->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC); 
    745     to->constants_updated = 1; 
    746   } 
    747 */ 
    748881#ifdef ZEND_ENGINE_2 
    749882        to->line_start = from->line_start; 
     
    762895        store_zval_hash(&to->constants_table, &from->constants_table); 
    763896        store_zval_hash(&to->default_properties, &from->default_properties); 
    764         store_hash(&to->properties_info, &from->properties_info, (store_bucket_t) store_property_info); 
     897        //store_hash(&to->properties_info, &from->properties_info, (store_bucket_t) store_property_info, NULL, NULL); 
     898        store_hash(&to->properties_info, &from->properties_info, (store_bucket_t) store_property_info, (check_bucket_t) store_property_access_check, from); 
     899#  ifdef ZEND_ENGINE_2_1 
     900        ea_debug_printf(EA_DEBUG, "[%d] store_class_entry: from->static_members(%x), from->default_static_members(%x)\n", getpid(), from->static_members, &from->default_static_members); 
     901        if((from->static_members != NULL) && (from->static_members != &from->default_static_members)) { 
     902                store_zval_hash(&to->default_static_members, &from->default_static_members); 
     903                EACCELERATOR_ALIGN(EAG(mem)); 
     904                to->static_members = (HashTable *) EAG(mem); 
     905                EAG(mem) += sizeof(HashTable); 
     906                store_hash(to->static_members, from->static_members, (store_bucket_t) store_zval_ptr, (check_bucket_t) store_static_member_access_check, from); 
     907        } else { 
     908                /*EACCELERATOR_ALIGN(EAG(mem)); 
     909                to->static_members = (HashTable *) EAG(mem); 
     910                EAG(mem) += sizeof(HashTable);*/ 
     911                store_hash(&to->default_static_members, &from->default_static_members, (store_bucket_t) store_zval_ptr, (check_bucket_t) store_static_member_access_check, from); 
     912                to->static_members = &to->default_static_members; 
     913        } 
     914        ea_debug_printf(EA_DEBUG, "[%d] store_class_entry: to->static_members(%x), to->default_static_members(%x)\n", getpid(), to->static_members, &to->default_static_members); 
     915#  else 
    765916        if (from->static_members != NULL) { 
    766917                EACCELERATOR_ALIGN(EAG(mem)); 
     
    769920                store_zval_hash(to->static_members, from->static_members); 
    770921        } 
     922#  endif 
    771923#else 
    772924        store_zval_hash(&to->default_properties, &from->default_properties); 
    773925#endif 
    774         store_hash(&to->function_table, &from->function_table, (store_bucket_t) store_op_array); 
     926        store_hash(&to->function_table, &from->function_table, (store_bucket_t) store_op_array, (check_bucket_t) store_function_inheritance_check, from); 
    775927 
    776928#ifdef DEBUG