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

Generated by: LCOV version 1.10

Generated at Tue, 14 Oct 2014 07:25:44 +0000 (6 days ago)

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