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: 289 504 57.3 %
Date: 2015-05-21 Functions: 19 21 90.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Thu, 21 May 2015 19:58:59 +0000 (3 days ago)

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