Changeset 162 for eaccelerator/trunk/ea_store.c
- Timestamp:
- 02/17/06 18:35:50 (3 years ago)
- Files:
-
- eaccelerator/trunk/ea_store.c (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
eaccelerator/trunk/ea_store.c
r124 r162 83 83 EAG(mem) += sizeof(zend_property_info); 84 84 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 85 90 } 86 91 … … 118 123 case IS_CONSTANT: 119 124 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 {*/ 122 127 calc_string(zv->value.str.val, zv->value.str.len + 1 TSRMLS_CC); 123 } 128 /* }*/ 124 129 break; 125 130 case IS_ARRAY: … … 247 252 calc_zval_hash(from->static_variables); 248 253 } 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 249 264 if (from->filename != NULL) 250 265 calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); … … 270 285 calc_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 271 286 #ifdef ZEND_ENGINE_2 272 #if 0273 // 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 #endif281 287 if (from->filename != NULL) 282 288 calc_string(from->filename, strlen(from->filename) + 1 TSRMLS_CC); … … 286 292 calc_zval_hash(&from->constants_table); 287 293 calc_zval_hash(&from->default_properties); 294 288 295 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 289 301 if (from->static_members != NULL) { 302 # endif 290 303 EACCELERATOR_ALIGN(EAG(mem)); 291 304 EAG(mem) += sizeof(HashTable); … … 368 381 369 382 typedef 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) 383 typedef 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__) 376 390 377 391 #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) 379 393 380 394 #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) 382 396 383 397 static zval *store_zval_ptr(zval * from TSRMLS_DC) … … 393 407 394 408 static 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, ...) 396 411 { 397 412 Bucket *p, *np, *prev_p; 413 TSRMLS_FETCH(); 398 414 399 415 memcpy(target, source, sizeof(HashTable)); … … 416 432 np = NULL; 417 433 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 418 449 EACCELERATOR_ALIGN(EAG(mem)); 419 450 np = (Bucket *) EAG(mem); … … 466 497 case IS_CONSTANT: 467 498 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); 475 500 break; 476 501 case IS_ARRAY: … … 516 541 517 542 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", 519 544 getpid(), from->function_name ? from->function_name : "(top)", 520 545 #ifdef ZEND_ENGINE_2 … … 523 548 "NULL" 524 549 #endif 550 , from->type 525 551 ); 526 552 … … 555 581 to->arg_info[i].class_name_len = from->arg_info[i].class_name_len; 556 582 } 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 557 587 to->arg_info[i].allow_null = from->arg_info[i].allow_null; 558 588 to->arg_info[i].pass_by_reference = from->arg_info[i].pass_by_reference; … … 595 625 #endif 596 626 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 } 599 634 600 635 to->opcodes = from->opcodes; … … 672 707 store_zval_hash(to->static_variables, from->static_variables); 673 708 } 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 674 725 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); 676 727 } 677 728 #ifdef ZEND_ENGINE_2 … … 694 745 memcpy(to, from, sizeof(zend_property_info)); 695 746 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 696 753 return to; 697 754 } 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 */ 769 static 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 785 static 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 */ 837 static 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 } 699 847 700 848 eaccelerator_class_entry *store_class_entry(zend_class_entry * from TSRMLS_DC) … … 705 853 EAG(mem) += sizeof(eaccelerator_class_entry); 706 854 to->type = from->type; 855 ea_debug_printf(EA_DEBUG, "[%d] store_class_entry: class type=%d\n", getpid(), from->type); 707 856 to->name = NULL; 708 857 to->name_length = from->name_length; … … 712 861 to->static_members = NULL; 713 862 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; 727 866 #endif 728 867 … … 740 879 to->parent = store_string(from->parent->name, from->parent->name_length + 1 TSRMLS_CC); 741 880 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 */748 881 #ifdef ZEND_ENGINE_2 749 882 to->line_start = from->line_start; … … 762 895 store_zval_hash(&to->constants_table, &from->constants_table); 763 896 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 765 916 if (from->static_members != NULL) { 766 917 EACCELERATOR_ALIGN(EAG(mem)); … … 769 920 store_zval_hash(to->static_members, from->static_members); 770 921 } 922 # endif 771 923 #else 772 924 store_zval_hash(&to->default_properties, &from->default_properties); 773 925 #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); 775 927 776 928 #ifdef DEBUG