PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/opcache - zend_accelerator_util_funcs.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 266 491 54.2 %
Date: 2014-10-30 Functions: 20 23 87.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend OPcache                                                         |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP license,      |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    |          Stanislav Malyshev <stas@zend.com>                          |
      18             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      19             :    +----------------------------------------------------------------------+
      20             : */
      21             : 
      22             : #include "zend_API.h"
      23             : #include "zend_constants.h"
      24             : #include "zend_accelerator_util_funcs.h"
      25             : #include "zend_persist.h"
      26             : #include "zend_shared_alloc.h"
      27             : 
      28             : #define ZEND_PROTECTED_REFCOUNT (1<<30)
      29             : 
      30             : static uint32_t zend_accel_refcount = ZEND_PROTECTED_REFCOUNT;
      31             : 
      32             : #if SIZEOF_SIZE_T <= SIZEOF_ZEND_LONG
      33             : /* If sizeof(void*) == sizeof(ulong) we can use zend_hash index functions */
      34             : # define accel_xlat_set(old, new)       zend_hash_index_update_ptr(&ZCG(bind_hash), (zend_ulong)(zend_uintptr_t)(old), (new))
      35             : # define accel_xlat_get(old)            zend_hash_index_find_ptr(&ZCG(bind_hash), (zend_ulong)(zend_uintptr_t)(old))
      36             : #else
      37             : # define accel_xlat_set(old, new)       (zend_hash_str_add_ptr(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (zend_ulong)(zend_uintptr_t)(old), (void**)&(new))
      38             : # define accel_xlat_get(old, new)       ((new) = zend_hash_str_find_ptr(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (zend_ulong)(zend_uintptr_t)(old), (void**)&(new)))
      39             : #endif
      40             : 
      41             : #define ARENA_REALLOC(ptr) \
      42             :         (void*)(((char*)(ptr)) + ((char*)ZCG(arena_mem) - (char*)ZCG(current_persistent_script)->arena_mem))
      43             : 
      44             : typedef int (*id_function_t)(void *, void *);
      45             : typedef void (*unique_copy_ctor_func_t)(void *pElement);
      46             : 
      47             : static const uint32_t uninitialized_bucket = {INVALID_IDX};
      48             : 
      49             : static int zend_prepare_function_for_execution(zend_op_array *op_array);
      50             : static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind);
      51             : static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC);
      52             : 
      53           0 : static void zend_accel_destroy_zend_function(zval *zv)
      54             : {
      55           0 :         zend_function *function = Z_PTR_P(zv);
      56             :         TSRMLS_FETCH();
      57             : 
      58           0 :         if (function->type == ZEND_USER_FUNCTION) {
      59           0 :                 if (function->op_array.static_variables) {
      60             : 
      61           0 :                         FREE_HASHTABLE(function->op_array.static_variables);
      62           0 :                         function->op_array.static_variables = NULL;
      63             :                 }
      64             :         }
      65             : 
      66           0 :         destroy_zend_function(function TSRMLS_CC);
      67           0 : }
      68             : 
      69           0 : static void zend_accel_destroy_zend_class(zval *zv)
      70             : {
      71           0 :         zend_class_entry *ce = Z_PTR_P(zv);
      72           0 :         ce->function_table.pDestructor = zend_accel_destroy_zend_function;
      73           0 :         destroy_zend_class(zv);
      74           0 : }
      75             : 
      76         423 : zend_persistent_script* create_persistent_script(void)
      77             : {
      78         423 :         zend_persistent_script *persistent_script = (zend_persistent_script *) emalloc(sizeof(zend_persistent_script));
      79         423 :         memset(persistent_script, 0, sizeof(zend_persistent_script));
      80             : 
      81         423 :         zend_hash_init(&persistent_script->function_table, 128, NULL, ZEND_FUNCTION_DTOR, 0);
      82             :         /* class_table is usually destroyed by free_persistent_script() that
      83             :          * overrides destructor. ZEND_CLASS_DTOR may be used by standard
      84             :          * PHP compiler
      85             :          */
      86         423 :         zend_hash_init(&persistent_script->class_table, 16, NULL, ZEND_CLASS_DTOR, 0);
      87             : 
      88         423 :         return persistent_script;
      89             : }
      90             : 
      91           1 : void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements)
      92             : {
      93           1 :         if (destroy_elements) {
      94           1 :                 persistent_script->function_table.pDestructor = zend_accel_destroy_zend_function;
      95           1 :                 persistent_script->class_table.pDestructor = zend_accel_destroy_zend_class;
      96             :         } else {
      97           0 :                 persistent_script->function_table.pDestructor = NULL;
      98           0 :                 persistent_script->class_table.pDestructor = NULL;
      99             :         }
     100             : 
     101           1 :         zend_hash_destroy(&persistent_script->function_table);
     102           1 :         zend_hash_destroy(&persistent_script->class_table);
     103             : 
     104           1 :         if (persistent_script->full_path) {
     105           0 :                 efree(persistent_script->full_path);
     106             :         }
     107             : 
     108           1 :         efree(persistent_script);
     109           1 : }
     110             : 
     111        2231 : static int is_not_internal_function(zval *zv)
     112             : {
     113        2231 :         zend_function *function = Z_PTR_P(zv);
     114        2231 :         return(function->type != ZEND_INTERNAL_FUNCTION);
     115             : }
     116             : 
     117           1 : void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC)
     118             : {
     119           1 :         dtor_func_t orig_dtor = ht->pDestructor;
     120             : 
     121           1 :         ht->pDestructor = NULL;
     122           1 :         zend_hash_apply(ht, (apply_func_t) is_not_internal_function TSRMLS_CC);
     123           1 :         ht->pDestructor = orig_dtor;
     124           1 : }
     125             : 
     126      941498 : static int move_user_function(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) 
     127             : {
     128      941498 :         zend_function *function = Z_PTR_P(zv);
     129      941498 :         HashTable *function_table = va_arg(args, HashTable *);
     130             :         (void)num_args; /* keep the compiler happy */
     131             : 
     132      941498 :         if (function->type == ZEND_USER_FUNCTION) {
     133          24 :                 zend_hash_update_ptr(function_table, hash_key->key, function);
     134          24 :                 return 1;
     135             :         } else {
     136      941474 :                 return 0;
     137             :         }
     138             : }
     139             : 
     140         422 : void zend_accel_move_user_functions(HashTable *src, HashTable *dst TSRMLS_DC)
     141             : {
     142         422 :         dtor_func_t orig_dtor = src->pDestructor;
     143             : 
     144         422 :         src->pDestructor = NULL;
     145         422 :         zend_hash_apply_with_arguments(src TSRMLS_CC, (apply_func_args_t)move_user_function, 1, dst);
     146         422 :         src->pDestructor = orig_dtor;
     147         422 : }
     148             : 
     149    45216245 : static int copy_internal_function(zval *zv, HashTable *function_table TSRMLS_DC)
     150             : {
     151    45216245 :         zend_internal_function *function = Z_PTR_P(zv);
     152    45216245 :         if (function->type == ZEND_INTERNAL_FUNCTION) {
     153    45216245 :                 zend_hash_update_mem(function_table, function->function_name, function, sizeof(zend_internal_function));
     154             :         }
     155    45216245 :         return 0;
     156             : }
     157             : 
     158       20303 : void zend_accel_copy_internal_functions(TSRMLS_D)
     159             : {
     160       20303 :         zend_hash_apply_with_argument(CG(function_table), (apply_func_arg_t)copy_internal_function, &ZCG(function_table) TSRMLS_CC);
     161       20303 :         ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table));
     162       20303 : }
     163             : 
     164           2 : static void zend_destroy_property_info(zval *zv)
     165             : {
     166           2 :         zend_property_info *property_info = Z_PTR_P(zv);
     167             : 
     168           2 :         zend_string_release(property_info->name);
     169           2 :         if (property_info->doc_comment) {
     170           0 :                 zend_string_release(property_info->doc_comment);
     171             :         }
     172           2 : }
     173             : 
     174          29 : static inline zend_string *zend_clone_str(zend_string *str TSRMLS_DC)
     175             : {
     176             :         zend_string *ret;
     177             : 
     178          29 :         if (IS_INTERNED(str)) {         
     179          29 :                 ret = str;
     180           0 :         } else if (GC_REFCOUNT(str) <= 1 || (ret = accel_xlat_get(str)) == NULL) {
     181           0 :                 ret = zend_string_dup(str, 0);
     182           0 :                 GC_FLAGS(ret) = GC_FLAGS(str);
     183           0 :                 if (GC_REFCOUNT(str) > 1) {
     184           0 :                         accel_xlat_set(str, ret);
     185             :                 }
     186             :         } else {
     187           0 :                 GC_REFCOUNT(ret)++;
     188             :         }
     189          29 :         return ret;
     190             : }
     191             : 
     192          20 : static inline void zend_clone_zval(zval *src, int bind TSRMLS_DC)
     193             : {
     194             :         void *ptr;
     195             : 
     196          20 :         if (Z_IMMUTABLE_P(src)) {
     197          12 :                 return;
     198             :         }
     199             : 
     200           8 :         switch (Z_TYPE_P(src)) {
     201             :                 case IS_STRING:
     202             :             case IS_CONSTANT:
     203           1 :                         Z_STR_P(src) = zend_clone_str(Z_STR_P(src) TSRMLS_CC);
     204           1 :                         break;
     205             :                 case IS_ARRAY:
     206           0 :                         if (Z_ARR_P(src) != &EG(symbol_table)) {
     207           0 :                         if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_ARR_P(src))) != NULL) {
     208           0 :                                 Z_ARR_P(src) = ptr;
     209             :                                 } else {
     210           0 :                                         zend_array *old = Z_ARR_P(src);
     211             : 
     212           0 :                                         Z_ARR_P(src) = emalloc(sizeof(zend_array));
     213           0 :                                         Z_ARR_P(src)->gc = old->gc;
     214           0 :                                 if (bind && Z_REFCOUNT_P(src) > 1) {
     215           0 :                                                 accel_xlat_set(old, Z_ARR_P(src));
     216             :                                         }
     217           0 :                                         zend_hash_clone_zval(Z_ARRVAL_P(src), &old->ht, 0);
     218             :                                 }
     219             :                         }
     220           0 :                         break;
     221             :             case IS_REFERENCE:
     222           0 :                 if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_REF_P(src))) != NULL) {
     223           0 :                         Z_REF_P(src) = ptr;
     224             :                         } else {
     225           0 :                                 zend_reference *old = Z_REF_P(src);
     226           0 :                                 ZVAL_NEW_REF(src, &old->val);
     227           0 :                                 Z_REF_P(src)->gc = old->gc;
     228           0 :                         if (bind && Z_REFCOUNT_P(src) > 1) {
     229           0 :                                         accel_xlat_set(old, Z_REF_P(src));
     230             :                                 }
     231           0 :                                 zend_clone_zval(Z_REFVAL_P(src), bind TSRMLS_CC);
     232             :                         }
     233           0 :                 break;
     234             :             case IS_CONSTANT_AST:
     235           0 :                 if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) {
     236           0 :                         Z_AST_P(src) = ptr;
     237             :                         } else {
     238           0 :                                 zend_ast_ref *old = Z_AST_P(src);
     239             : 
     240           0 :                         ZVAL_NEW_AST(src, old->ast);
     241           0 :                                 Z_AST_P(src)->gc = old->gc;
     242           0 :                         if (bind && Z_REFCOUNT_P(src) > 1) {
     243           0 :                                         accel_xlat_set(old, Z_AST_P(src));
     244             :                                 }
     245           0 :                         Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src) TSRMLS_CC);
     246             :                         }
     247             :                 break;
     248             :         }
     249             : }
     250             : 
     251           0 : static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC)
     252             : {
     253             :         uint32_t i;
     254             : 
     255           0 :         if (ast->kind == ZEND_AST_ZVAL) {
     256           0 :                 zend_ast_zval *copy = emalloc(sizeof(zend_ast_zval));
     257           0 :                 copy->kind = ZEND_AST_ZVAL;
     258           0 :                 copy->attr = ast->attr;
     259           0 :                 ZVAL_COPY_VALUE(&copy->val, zend_ast_get_zval(ast));
     260           0 :                 zend_clone_zval(&copy->val, 0 TSRMLS_CC);
     261           0 :                 return (zend_ast *) copy;
     262           0 :         } else if (zend_ast_is_list(ast)) {
     263           0 :                 zend_ast_list *list = zend_ast_get_list(ast);
     264           0 :                 zend_ast_list *copy = emalloc(
     265             :                         sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
     266           0 :                 copy->kind = list->kind;
     267           0 :                 copy->attr = list->attr;
     268           0 :                 copy->children = list->children;
     269           0 :                 for (i = 0; i < list->children; i++) {
     270           0 :                         if (list->child[i]) {
     271           0 :                                 copy->child[i] = zend_ast_clone(list->child[i] TSRMLS_CC);
     272             :                         } else {
     273           0 :                                 copy->child[i] = NULL;
     274             :                         }
     275             :                 }
     276           0 :                 return (zend_ast *) copy;
     277             :         } else {
     278           0 :                 uint32_t children = zend_ast_get_num_children(ast);
     279           0 :                 zend_ast *copy = emalloc(sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children);
     280           0 :                 copy->kind = ast->kind;
     281           0 :                 copy->attr = ast->attr;
     282           0 :                 for (i = 0; i < children; i++) {
     283           0 :                         if (ast->child[i]) {
     284           0 :                                 copy->child[i] = zend_ast_clone(ast->child[i] TSRMLS_CC);
     285             :                         } else {
     286           0 :                                 copy->child[i] = NULL;
     287             :                         }
     288             :                 }
     289           0 :                 return copy;
     290             :         }
     291             : }
     292             : 
     293          14 : static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
     294             : {
     295             :         uint idx;
     296             :         Bucket *p, *q, *r;
     297             :         zend_ulong nIndex;
     298             :         TSRMLS_FETCH();
     299             : 
     300          14 :         ht->nTableSize = source->nTableSize;
     301          14 :         ht->nTableMask = source->nTableMask;
     302          14 :         ht->nNumUsed = 0;
     303          14 :         ht->nNumOfElements = source->nNumOfElements;
     304          14 :         ht->nNextFreeElement = source->nNextFreeElement;
     305          14 :         ht->pDestructor = ZVAL_PTR_DTOR;
     306          14 :         ht->u.flags = HASH_FLAG_APPLY_PROTECTION;
     307          14 :         ht->arData = NULL;
     308          14 :         ht->arHash = NULL;
     309          14 :         ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX;
     310             : 
     311          14 :         if (!ht->nTableMask) {
     312           0 :                 ht->arHash = (uint32_t*)&uninitialized_bucket;
     313           0 :                 return;
     314             :         }
     315             : 
     316          14 :         if (source->u.flags & HASH_FLAG_PACKED) {
     317           0 :                 ht->u.flags |= HASH_FLAG_PACKED;
     318           0 :                 ht->arData = (Bucket *) emalloc(ht->nTableSize * sizeof(Bucket));
     319           0 :                 ht->arHash = (uint32_t*)&uninitialized_bucket;
     320             :         
     321           0 :                 for (idx = 0; idx < source->nNumUsed; idx++) {
     322           0 :                         p = source->arData + idx;
     323           0 :                         if (Z_TYPE(p->val) == IS_UNDEF) continue;
     324           0 :                         nIndex = p->h & ht->nTableMask;
     325             : 
     326           0 :                         r = ht->arData + ht->nNumUsed;
     327           0 :                         q = ht->arData + p->h;
     328           0 :                         while (r != q) {
     329           0 :                                 ZVAL_UNDEF(&r->val);
     330           0 :                                 r++;
     331             :                         }
     332           0 :                         ht->nNumUsed = p->h + 1;
     333             : 
     334             :                         /* Initialize key */
     335           0 :                         q->h = p->h;
     336           0 :                         q->key = NULL;
     337             : 
     338             :                         /* Copy data */
     339           0 :                         ZVAL_COPY_VALUE(&q->val, &p->val);
     340           0 :                         zend_clone_zval(&q->val, bind TSRMLS_CC);
     341             :                 }
     342             :         } else {
     343          14 :                 ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)));
     344          14 :                 ht->arHash = (uint32_t*)(ht->arData + ht->nTableSize);
     345          14 :                 memset(ht->arHash, INVALID_IDX, sizeof(uint32_t) * ht->nTableSize);
     346             :         
     347          32 :                 for (idx = 0; idx < source->nNumUsed; idx++) {
     348          18 :                         p = source->arData + idx;
     349          36 :                         if (Z_TYPE(p->val) == IS_UNDEF) continue;
     350          18 :                         nIndex = p->h & ht->nTableMask;
     351             : 
     352             :                         /* Insert into hash collision list */
     353          18 :                         q = ht->arData + ht->nNumUsed;
     354          18 :                         Z_NEXT(q->val) = ht->arHash[nIndex];
     355          18 :                         ht->arHash[nIndex] = ht->nNumUsed++;
     356             : 
     357             :                         /* Initialize key */
     358          18 :                         q->h = p->h;
     359          18 :                         if (!p->key) {
     360           0 :                                 q->key = NULL;
     361             :                         } else {
     362          18 :                                 q->key = zend_clone_str(p->key TSRMLS_CC);
     363             :                         }
     364             : 
     365             :                         /* Copy data */
     366          18 :                         ZVAL_COPY_VALUE(&q->val, &p->val);
     367          18 :                         zend_clone_zval(&q->val, bind TSRMLS_CC);
     368             :                 }
     369             :         }
     370             : }
     371             : 
     372           1 : static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
     373             : {
     374             :         uint idx;
     375             :         Bucket *p, *q;
     376             :         zend_ulong nIndex;
     377             :         zend_class_entry *new_ce;
     378             :         zend_function *new_prototype;
     379             :         zend_op_array *new_entry;
     380             : 
     381           1 :         ht->nTableSize = source->nTableSize;
     382           1 :         ht->nTableMask = source->nTableMask;
     383           1 :         ht->nNumUsed = 0;
     384           1 :         ht->nNumOfElements = source->nNumOfElements;
     385           1 :         ht->nNextFreeElement = source->nNextFreeElement;
     386           1 :         ht->pDestructor = ZEND_FUNCTION_DTOR;
     387           1 :         ht->u.flags = 0;
     388           1 :         ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX;
     389             : 
     390           1 :         if (!ht->nTableMask) {
     391           0 :                 ht->arHash = (uint32_t*)&uninitialized_bucket;
     392           0 :                 return;
     393             :         }
     394             : 
     395             :         ZEND_ASSERT(!(source->u.flags & HASH_FLAG_PACKED));
     396           1 :         ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)));
     397           1 :         ht->arHash = (uint32_t *)(ht->arData + ht->nTableSize);
     398           1 :         memset(ht->arHash, INVALID_IDX, sizeof(uint32_t) * ht->nTableSize);
     399             : 
     400           6 :         for (idx = 0; idx < source->nNumUsed; idx++) {            
     401           5 :                 p = source->arData + idx;
     402          10 :                 if (Z_TYPE(p->val) == IS_UNDEF) continue;
     403             : 
     404           5 :                 nIndex = p->h & ht->nTableMask;
     405             : 
     406             :                 /* Insert into hash collision list */
     407           5 :                 q = ht->arData + ht->nNumUsed;
     408           5 :                 Z_NEXT(q->val) = ht->arHash[nIndex];
     409           5 :                 ht->arHash[nIndex] = ht->nNumUsed++;
     410             : 
     411             :                 /* Initialize key */
     412           5 :                 q->h = p->h;
     413             :                 ZEND_ASSERT(p->key != NULL);
     414           5 :                 q->key = zend_clone_str(p->key TSRMLS_CC);
     415             : 
     416             :                 /* Copy data */
     417           5 :                 ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val)));
     418           5 :                 new_entry = (zend_op_array*)Z_PTR(q->val);
     419             : 
     420             :                 /* Copy constructor */
     421             :                 /* we use refcount to show that op_array is referenced from several places */
     422           5 :                 if (new_entry->refcount != NULL) {
     423           0 :                         accel_xlat_set(Z_PTR(p->val), new_entry);
     424             :                 }
     425             : 
     426           5 :                 zend_prepare_function_for_execution(new_entry);
     427             : 
     428           5 :                 if (old_ce == new_entry->scope) {
     429           5 :                         new_entry->scope = ce;
     430             :                 } else {
     431           0 :                         if ((new_ce = accel_xlat_get(new_entry->scope)) != NULL) {
     432           0 :                                 new_entry->scope = new_ce;
     433             :                         } else {
     434           0 :                                 zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val);
     435             :                         }
     436             :                 }
     437             : 
     438             :                 /* update prototype */
     439           5 :                 if (new_entry->prototype) {
     440           0 :                         if ((new_prototype = accel_xlat_get(new_entry->prototype)) != NULL) {
     441           0 :                                 new_entry->prototype = new_prototype;
     442             :                         } else {
     443           0 :                                 zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val);
     444             :                         }
     445             :                 }
     446             :         }
     447             : }
     448             : 
     449           1 : static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
     450             : {
     451             :         uint idx;
     452             :         Bucket *p, *q;
     453             :         zend_ulong nIndex;
     454             :         zend_class_entry *new_ce;
     455             :         zend_property_info *prop_info;
     456             : 
     457           1 :         ht->nTableSize = source->nTableSize;
     458           1 :         ht->nTableMask = source->nTableMask;
     459           1 :         ht->nNumUsed = 0;
     460           1 :         ht->nNumOfElements = source->nNumOfElements;
     461           1 :         ht->nNextFreeElement = source->nNextFreeElement;
     462           1 :         ht->pDestructor = zend_destroy_property_info;
     463           1 :         ht->u.flags = 0;
     464           1 :         ht->nInternalPointer = source->nNumOfElements ? 0 : INVALID_IDX;
     465             : 
     466           1 :         if (!ht->nTableMask) {
     467           0 :                 ht->arHash = (uint32_t*)&uninitialized_bucket;
     468           0 :                 return;
     469             :         }
     470             : 
     471             :         ZEND_ASSERT(!(source->u.flags & HASH_FLAG_PACKED));
     472           1 :         ht->arData = (Bucket *) emalloc(ht->nTableSize * (sizeof(Bucket) + sizeof(uint32_t)));
     473           1 :         ht->arHash = (uint32_t*)(ht->arData + ht->nTableSize);
     474           1 :         memset(ht->arHash, INVALID_IDX, sizeof(uint32_t) * ht->nTableSize);
     475             : 
     476           3 :         for (idx = 0; idx < source->nNumUsed; idx++) {            
     477           2 :                 p = source->arData + idx;
     478           4 :                 if (Z_TYPE(p->val) == IS_UNDEF) continue;
     479             : 
     480           2 :                 nIndex = p->h & ht->nTableMask;
     481             : 
     482             :                 /* Insert into hash collision list */
     483           2 :                 q = ht->arData + ht->nNumUsed;
     484           2 :                 Z_NEXT(q->val) = ht->arHash[nIndex];
     485           2 :                 ht->arHash[nIndex] = ht->nNumUsed++;
     486             : 
     487             :                 /* Initialize key */
     488           2 :                 q->h = p->h;
     489             :                 ZEND_ASSERT(p->key != NULL);
     490           2 :                 q->key = zend_clone_str(p->key TSRMLS_CC);
     491             : 
     492             :                 /* Copy data */
     493           2 :                 ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val)));
     494           2 :                 prop_info = Z_PTR(q->val);
     495             : 
     496             :                 /* Copy constructor */
     497           2 :                 prop_info->name = zend_clone_str(prop_info->name TSRMLS_CC);
     498           2 :                 if (prop_info->doc_comment) {
     499           0 :                         if (ZCG(accel_directives).load_comments) {
     500           0 :                                 prop_info->doc_comment = zend_string_dup(prop_info->doc_comment, 0);
     501             :                         } else {
     502           0 :                                 prop_info->doc_comment = NULL;
     503             :                         }
     504             :                 }
     505           2 :                 if (prop_info->ce == old_ce) {
     506           2 :                         prop_info->ce = ce;
     507           0 :                 } else if ((new_ce = accel_xlat_get(prop_info->ce)) != NULL) {
     508           0 :                         prop_info->ce = new_ce;
     509             :                 } else {
     510           0 :                         zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name->val, prop_info->name->val);
     511             :                 }
     512             :         }
     513             : }
     514             : 
     515             : /* protects reference count, creates copy of statics */
     516         451 : static int zend_prepare_function_for_execution(zend_op_array *op_array)
     517             : {
     518         451 :         HashTable *shared_statics = op_array->static_variables;
     519             : 
     520             :         /* protect reference count */
     521         451 :         op_array->refcount = &zend_accel_refcount;
     522         451 :         (*op_array->refcount) = ZEND_PROTECTED_REFCOUNT;
     523             : 
     524             :         /* copy statics */
     525         451 :         if (shared_statics) {
     526          13 :                 ALLOC_HASHTABLE(op_array->static_variables);
     527          13 :                 zend_hash_clone_zval(op_array->static_variables, shared_statics, 0);
     528             :         }
     529             : 
     530         451 :         return 0;
     531             : }
     532             : 
     533             : #define zend_update_inherited_handler(handler) \
     534             : { \
     535             :         if (ce->handler != NULL) { \
     536             :                 if ((new_func = accel_xlat_get(ce->handler)) != NULL) { \
     537             :                         ce->handler = new_func; \
     538             :                 } else { \
     539             :                         zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name->val); \
     540             :                 } \
     541             :         } \
     542             : }
     543             : 
     544             : /* Protects class' refcount, copies default properties, functions and class name */
     545           1 : static void zend_class_copy_ctor(zend_class_entry **pce)
     546             : {
     547           1 :         zend_class_entry *ce = *pce;
     548           1 :         zend_class_entry *old_ce = ce;
     549             :         zend_class_entry *new_ce;
     550             :         zend_function *new_func;
     551             :         TSRMLS_FETCH();
     552             : 
     553           1 :         *pce = ce = ARENA_REALLOC(old_ce);
     554           1 :         ce->refcount = 1;
     555             : 
     556           1 :         if (old_ce->refcount != 1) {
     557             :                 /* this class is not used as a parent for any other classes */
     558           0 :                 accel_xlat_set(old_ce, ce);
     559             :         }
     560             : 
     561           1 :         if (old_ce->default_properties_table) {
     562             :                 int i;
     563             : 
     564           0 :                 ce->default_properties_table = emalloc(sizeof(zval) * old_ce->default_properties_count);
     565           0 :                 for (i = 0; i < old_ce->default_properties_count; i++) {
     566           0 :                         ZVAL_COPY_VALUE(&ce->default_properties_table[i], &old_ce->default_properties_table[i]);
     567           0 :                         zend_clone_zval(&ce->default_properties_table[i], 1 TSRMLS_CC);
     568             :                 }
     569             :         }
     570             : 
     571           1 :         zend_hash_clone_methods(&ce->function_table, &old_ce->function_table, old_ce, ce TSRMLS_CC);
     572             : 
     573             :         /* static members */
     574           1 :         if (old_ce->default_static_members_table) {
     575             :                 int i;
     576             : 
     577           1 :                 ce->default_static_members_table = emalloc(sizeof(zval) * old_ce->default_static_members_count);
     578           3 :                 for (i = 0; i < old_ce->default_static_members_count; i++) {
     579           2 :                         ZVAL_COPY_VALUE(&ce->default_static_members_table[i], &old_ce->default_static_members_table[i]);
     580           2 :                         zend_clone_zval(&ce->default_static_members_table[i], 1 TSRMLS_CC);
     581             :                 }
     582             :         }
     583           1 :         ce->static_members_table = ce->default_static_members_table;
     584             : 
     585             :         /* properties_info */
     586           1 :         zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce, ce TSRMLS_CC);
     587             : 
     588             :         /* constants table */
     589           1 :         zend_hash_clone_zval(&ce->constants_table, &old_ce->constants_table, 1);
     590           1 :         ce->constants_table.u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
     591             : 
     592           1 :         ce->name = zend_clone_str(ce->name TSRMLS_CC);
     593             : 
     594             :         /* interfaces aren't really implemented, so we create a new table */
     595           1 :         if (ce->num_interfaces) {
     596           0 :                 ce->interfaces = emalloc(sizeof(zend_class_entry *) * ce->num_interfaces);
     597           0 :                 memset(ce->interfaces, 0, sizeof(zend_class_entry *) * ce->num_interfaces);
     598             :         } else {
     599           1 :                 ce->interfaces = NULL;
     600             :         }
     601           1 :         if (ZEND_CE_DOC_COMMENT(ce)) {
     602           0 :                 if (ZCG(accel_directives).load_comments) {
     603           0 :                         ZEND_CE_DOC_COMMENT(ce) = zend_string_dup(ZEND_CE_DOC_COMMENT(ce), 0);
     604             :                 } else {
     605           0 :                         ZEND_CE_DOC_COMMENT(ce) =  NULL;
     606             :                 }
     607             :         }
     608             : 
     609           1 :         if (ce->parent) {
     610           0 :                 if ((new_ce = accel_xlat_get(ce->parent)) != NULL) {
     611           0 :                         ce->parent = new_ce;
     612             :                 } else {
     613           0 :                         zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name->val);
     614             :                 }
     615             :         }
     616             : 
     617           1 :         zend_update_inherited_handler(constructor);
     618           1 :         zend_update_inherited_handler(destructor);
     619           1 :         zend_update_inherited_handler(clone);
     620           1 :         zend_update_inherited_handler(__get);
     621           1 :         zend_update_inherited_handler(__set);
     622           1 :         zend_update_inherited_handler(__call);
     623             : /* 5.1 stuff */
     624           1 :         zend_update_inherited_handler(serialize_func);
     625           1 :         zend_update_inherited_handler(unserialize_func);
     626           1 :         zend_update_inherited_handler(__isset);
     627           1 :         zend_update_inherited_handler(__unset);
     628             : /* 5.2 stuff */
     629           1 :         zend_update_inherited_handler(__tostring);
     630             : 
     631             : /* 5.3 stuff */
     632           1 :         zend_update_inherited_handler(__callstatic);
     633           1 :         zend_update_inherited_handler(__debugInfo);
     634             : 
     635             : /* 5.4 traits */
     636           1 :         if (ce->trait_aliases) {
     637             :                 zend_trait_alias **trait_aliases;
     638           0 :                 int i = 0;
     639             : 
     640           0 :                 while (ce->trait_aliases[i]) {
     641           0 :                         i++;
     642             :                 }
     643           0 :                 trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1));
     644           0 :                 i = 0;
     645           0 :                 while (ce->trait_aliases[i]) {
     646           0 :                         trait_aliases[i] = emalloc(sizeof(zend_trait_alias));
     647           0 :                         memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias));
     648           0 :                         trait_aliases[i]->trait_method = emalloc(sizeof(zend_trait_method_reference));
     649           0 :                         memcpy(trait_aliases[i]->trait_method, ce->trait_aliases[i]->trait_method, sizeof(zend_trait_method_reference));
     650           0 :                         if (trait_aliases[i]->trait_method) {
     651           0 :                                 if (trait_aliases[i]->trait_method->method_name) {
     652           0 :                                         trait_aliases[i]->trait_method->method_name =
     653           0 :                                                 zend_clone_str(trait_aliases[i]->trait_method->method_name TSRMLS_CC);
     654             :                                 }
     655           0 :                                 if (trait_aliases[i]->trait_method->class_name) {
     656           0 :                                         trait_aliases[i]->trait_method->class_name =
     657           0 :                                                 zend_clone_str(trait_aliases[i]->trait_method->class_name TSRMLS_CC);
     658             :                                 }
     659             :                         }
     660             : 
     661           0 :                         if (trait_aliases[i]->alias) {
     662           0 :                                 trait_aliases[i]->alias =
     663           0 :                                         zend_clone_str(trait_aliases[i]->alias TSRMLS_CC);
     664             :                         }
     665           0 :                         i++;
     666             :                 }
     667           0 :                 trait_aliases[i] = NULL;
     668           0 :                 ce->trait_aliases = trait_aliases;
     669             :         }
     670             : 
     671           1 :         if (ce->trait_precedences) {
     672             :                 zend_trait_precedence **trait_precedences;
     673           0 :                 int i = 0;
     674             : 
     675           0 :                 while (ce->trait_precedences[i]) {
     676           0 :                         i++;
     677             :                 }
     678           0 :                 trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1));
     679           0 :                 i = 0;
     680           0 :                 while (ce->trait_precedences[i]) {
     681           0 :                         trait_precedences[i] = emalloc(sizeof(zend_trait_precedence));
     682           0 :                         memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence));
     683           0 :                         trait_precedences[i]->trait_method = emalloc(sizeof(zend_trait_method_reference));
     684           0 :                         memcpy(trait_precedences[i]->trait_method, ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference));
     685             : 
     686           0 :                         trait_precedences[i]->trait_method->method_name =
     687           0 :                                 zend_clone_str(trait_precedences[i]->trait_method->method_name TSRMLS_CC);
     688           0 :                         trait_precedences[i]->trait_method->class_name =
     689           0 :                                 zend_clone_str(trait_precedences[i]->trait_method->class_name TSRMLS_CC);
     690             : 
     691           0 :                         if (trait_precedences[i]->exclude_from_classes) {
     692             :                                 zend_string **exclude_from_classes;
     693           0 :                                 int j = 0;
     694             : 
     695           0 :                                 while (trait_precedences[i]->exclude_from_classes[j].class_name) {
     696           0 :                                         j++;
     697             :                                 }
     698           0 :                                 exclude_from_classes = emalloc(sizeof(zend_string*) * (j + 1));
     699           0 :                                 j = 0;
     700           0 :                                 while (trait_precedences[i]->exclude_from_classes[j].class_name) {
     701           0 :                                         exclude_from_classes[j] =
     702           0 :                                                 zend_clone_str(trait_precedences[i]->exclude_from_classes[j].class_name TSRMLS_CC);
     703           0 :                                         j++;
     704             :                                 }
     705           0 :                                 exclude_from_classes[j] = NULL;
     706           0 :                                 trait_precedences[i]->exclude_from_classes = (void*)exclude_from_classes;
     707             :                         }
     708           0 :                         i++;
     709             :                 }
     710           0 :                 trait_precedences[i] = NULL;
     711           0 :                 ce->trait_precedences = trait_precedences;
     712             :         }
     713           1 : }
     714             : 
     715          24 : static void zend_accel_function_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor TSRMLS_DC)
     716             : {
     717             :         zend_function *function1, *function2;
     718             :         uint idx;
     719             :         Bucket *p;
     720             :         zval *t;
     721             : 
     722          48 :         for (idx = 0; idx < source->nNumUsed; idx++) {            
     723          24 :                 p = source->arData + idx;
     724          48 :                 if (Z_TYPE(p->val) == IS_UNDEF) continue;
     725          24 :                 if (p->key) {
     726          24 :                         t = zend_hash_add(target, p->key, &p->val);
     727          24 :                         if (UNEXPECTED(t == NULL)) {
     728           0 :                                 if (p->key->len > 0 && p->key->val[0] == 0) {
     729             :                                         /* Mangled key */
     730           0 :                                         t = zend_hash_update(target, p->key, &p->val);
     731             :                                 } else {
     732           0 :                                         t = zend_hash_find(target, p->key);
     733           0 :                                         goto failure;
     734             :                                 }
     735             :                         }
     736             :                 } else {
     737           0 :                     t = zend_hash_index_add(target, p->h, &p->val);
     738           0 :                         if (UNEXPECTED(t == NULL)) {
     739           0 :                                 t = zend_hash_index_find(target, p->h);                              
     740           0 :                                 goto failure;
     741             :                         }
     742             :                 }
     743          24 :                 if (pCopyConstructor) {
     744          24 :                         Z_PTR_P(t) = ARENA_REALLOC(Z_PTR(p->val));
     745          24 :                         pCopyConstructor(Z_PTR_P(t));
     746             :                 }
     747             :         }
     748          24 :         target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX;
     749          24 :         return;
     750             : 
     751             : failure:
     752           0 :         function1 = Z_PTR(p->val);
     753           0 :         function2 = Z_PTR_P(t);
     754           0 :         CG(in_compilation) = 1;
     755           0 :         zend_set_compiled_filename(function1->op_array.filename TSRMLS_CC);
     756           0 :         CG(zend_lineno) = function1->op_array.opcodes[0].lineno;
     757           0 :         if (function2->type == ZEND_USER_FUNCTION
     758           0 :                 && function2->op_array.last > 0) {
     759           0 :                 zend_error(E_ERROR, "Cannot redeclare %s() (previously declared in %s:%d)",
     760           0 :                                    function1->common.function_name->val,
     761           0 :                                    function2->op_array.filename->val,
     762           0 :                                    (int)function2->op_array.opcodes[0].lineno);
     763             :         } else {
     764           0 :                 zend_error(E_ERROR, "Cannot redeclare %s()", function1->common.function_name->val);
     765             :         }
     766             : }
     767             : 
     768           1 : static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor TSRMLS_DC)
     769             : {
     770             :         zend_class_entry *ce1;
     771             :         uint idx;
     772             :         Bucket *p;
     773             :         zval *t;
     774             : 
     775           3 :         for (idx = 0; idx < source->nNumUsed; idx++) {            
     776           2 :                 p = source->arData + idx;
     777           4 :                 if (Z_TYPE(p->val) == IS_UNDEF) continue;
     778           1 :                 if (p->key) {
     779           1 :                         t = zend_hash_add(target, p->key, &p->val);
     780           1 :                         if (UNEXPECTED(t == NULL)) {
     781           0 :                                 if (p->key->len > 0 && p->key->val[0] == 0) {
     782             :                                         /* Mangled key - ignore and wait for runtime */
     783           0 :                                         continue;
     784           0 :                                 } else if (!ZCG(accel_directives).ignore_dups) {
     785           0 :                                         t = zend_hash_find(target, p->key);
     786           0 :                                         goto failure;
     787             :                                 }
     788             :                         }
     789             :                 } else {
     790           0 :                         t = zend_hash_index_add(target, p->h, &p->val);
     791           0 :                         if (UNEXPECTED(t == NULL)) {
     792           0 :                                 if (!ZCG(accel_directives).ignore_dups) {
     793           0 :                                         t = zend_hash_index_find(target,p->h);
     794           0 :                                         goto failure;
     795             :                                 }
     796             :                         }
     797             :                 }
     798           1 :                 if (pCopyConstructor) {
     799           1 :                         pCopyConstructor(&Z_PTR_P(t));
     800             :                 }
     801             :         }
     802           1 :         target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX;
     803           1 :         return;
     804             : 
     805             : failure:
     806           0 :         ce1 = Z_PTR(p->val);
     807           0 :         CG(in_compilation) = 1;
     808           0 :         zend_set_compiled_filename(ce1->info.user.filename TSRMLS_CC);
     809           0 :         CG(zend_lineno) = ce1->info.user.line_start;
     810           0 :         zend_error(E_ERROR, "Cannot redeclare class %s", ce1->name->val);
     811             : }
     812             : 
     813         422 : zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory TSRMLS_DC)
     814             : {
     815             :         zend_op_array *op_array;
     816             : 
     817         422 :         op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     818         422 :         *op_array = persistent_script->main_op_array;
     819             : 
     820         422 :         if (EXPECTED(from_shared_memory)) {
     821         422 :                 zend_hash_init(&ZCG(bind_hash), 10, NULL, NULL, 0);
     822             : 
     823         422 :                 ZCG(current_persistent_script) = persistent_script;
     824         422 :                 ZCG(arena_mem) = NULL;
     825         422 :                 if (EXPECTED(persistent_script->arena_size)) {
     826          50 :                         ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size);
     827          25 :                         memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size);
     828             :                 }
     829             : 
     830             :                 /* Copy all the necessary stuff from shared memory to regular memory, and protect the shared script */
     831         422 :                 if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
     832           1 :                         zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, (unique_copy_ctor_func_t) zend_class_copy_ctor TSRMLS_CC);
     833             :                 }
     834             :                 /* we must first to copy all classes and then prepare functions, since functions may try to bind
     835             :                    classes - which depend on pre-bind class entries existent in the class table */
     836         422 :                 if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
     837          24 :                         zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table, (unique_copy_ctor_func_t)zend_prepare_function_for_execution TSRMLS_CC);
     838             :                 }
     839             : 
     840         422 :                 zend_prepare_function_for_execution(op_array);
     841             : 
     842             :                 /* Register __COMPILER_HALT_OFFSET__ constant */
     843         517 :                 if (persistent_script->compiler_halt_offset != 0 &&
     844          95 :                     persistent_script->full_path) {
     845             :                         zend_string *name;
     846          95 :                         char haltoff[] = "__COMPILER_HALT_OFFSET__";
     847             : 
     848          95 :                         name = zend_mangle_property_name(haltoff, sizeof(haltoff) - 1, persistent_script->full_path->val, persistent_script->full_path->len, 0);
     849          95 :                         if (!zend_hash_exists(EG(zend_constants), name)) {
     850           0 :                                 zend_register_long_constant(name->val, name->len, persistent_script->compiler_halt_offset, CONST_CS, 0 TSRMLS_CC);
     851             :                         }
     852             :                         zend_string_release(name);
     853             :                 }
     854             : 
     855         422 :                 zend_hash_destroy(&ZCG(bind_hash));
     856         422 :                 ZCG(current_persistent_script) = NULL;
     857             :         } else /* if (!from_shared_memory) */ {
     858           0 :                 if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
     859           0 :                         zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table, NULL TSRMLS_CC);
     860             :                 }
     861           0 :                 if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
     862           0 :                         zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, NULL TSRMLS_CC);
     863             :                 }
     864             :         }
     865             : 
     866         422 :         if (op_array->early_binding != (uint32_t)-1) {
     867           0 :                 zend_string *orig_compiled_filename = CG(compiled_filename);
     868           0 :                 CG(compiled_filename) = persistent_script->full_path;
     869           0 :                 zend_do_delayed_early_binding(op_array TSRMLS_CC);
     870           0 :                 CG(compiled_filename) = orig_compiled_filename;
     871             :         }
     872             : 
     873         422 :         if (UNEXPECTED(!from_shared_memory)) {
     874           0 :                 free_persistent_script(persistent_script, 0); /* free only hashes */
     875             :         }
     876             : 
     877         422 :         return op_array;
     878             : }
     879             : 
     880             : /*
     881             :  * zend_adler32() is based on zlib implementation
     882             :  * Computes the Adler-32 checksum of a data stream
     883             :  *
     884             :  * Copyright (C) 1995-2005 Mark Adler
     885             :  * For conditions of distribution and use, see copyright notice in zlib.h
     886             :  *
     887             :  * Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
     888             :  *
     889             :  *  This software is provided 'as-is', without any express or implied
     890             :  *  warranty.  In no event will the authors be held liable for any damages
     891             :  *  arising from the use of this software.
     892             :  *
     893             :  *  Permission is granted to anyone to use this software for any purpose,
     894             :  *  including commercial applications, and to alter it and redistribute it
     895             :  *  freely, subject to the following restrictions:
     896             :  *
     897             :  *  1. The origin of this software must not be misrepresented; you must not
     898             :  *     claim that you wrote the original software. If you use this software
     899             :  *     in a product, an acknowledgment in the product documentation would be
     900             :  *     appreciated but is not required.
     901             :  *  2. Altered source versions must be plainly marked as such, and must not be
     902             :  *     misrepresented as being the original software.
     903             :  *  3. This notice may not be removed or altered from any source distribution.
     904             :  *
     905             :  */
     906             : 
     907             : #define ADLER32_BASE 65521 /* largest prime smaller than 65536 */
     908             : #define ADLER32_NMAX 5552
     909             : /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
     910             : 
     911             : #define ADLER32_DO1(buf)        {s1 += *(buf); s2 += s1;}
     912             : #define ADLER32_DO2(buf, i)     ADLER32_DO1(buf + i); ADLER32_DO1(buf + i + 1);
     913             : #define ADLER32_DO4(buf, i)     ADLER32_DO2(buf, i); ADLER32_DO2(buf, i + 2);
     914             : #define ADLER32_DO8(buf, i)     ADLER32_DO4(buf, i); ADLER32_DO4(buf, i + 4);
     915             : #define ADLER32_DO16(buf)       ADLER32_DO8(buf, 0); ADLER32_DO8(buf, 8);
     916             : 
     917         844 : unsigned int zend_adler32(unsigned int checksum, signed char *buf, uint len)
     918             : {
     919         844 :         unsigned int s1 = checksum & 0xffff;
     920         844 :         unsigned int s2 = (checksum >> 16) & 0xffff;
     921             :         signed char *end;
     922             : 
     923        1698 :         while (len >= ADLER32_NMAX) {
     924          10 :                 len -= ADLER32_NMAX;
     925          10 :                 end = buf + ADLER32_NMAX;
     926             :                 do {
     927        3470 :                         ADLER32_DO16(buf);
     928        3470 :                         buf += 16;
     929        3470 :                 } while (buf != end);
     930          10 :                 s1 %= ADLER32_BASE;
     931          10 :                 s2 %= ADLER32_BASE;
     932             :         }
     933             : 
     934         844 :         if (len) {
     935         844 :                 if (len >= 16) {
     936         844 :                         end = buf + (len & 0xfff0);
     937         844 :                         len &= 0xf;
     938             :                         do {
     939       35545 :                                 ADLER32_DO16(buf);
     940       35545 :                                 buf += 16;
     941       35545 :                         } while (buf != end);
     942             :                 }
     943         844 :                 if (len) {
     944         627 :                         end = buf + len;
     945             :                         do {
     946        5016 :                                 ADLER32_DO1(buf);
     947        5016 :                                 buf++;
     948        5016 :                         } while (buf != end);
     949             :                 }
     950         844 :                 s1 %= ADLER32_BASE;
     951         844 :                 s2 %= ADLER32_BASE;
     952             :         }
     953             : 
     954         844 :         return (s2 << 16) | s1;
     955             : }

Generated by: LCOV version 1.10

Generated at Thu, 30 Oct 2014 07:41:34 +0000 (2 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.