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: 0 533 0.0 %
Date: 2014-04-06 Functions: 0 25 0.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 zend_uint zend_accel_refcount = ZEND_PROTECTED_REFCOUNT;
      31             : 
      32             : #if SIZEOF_SIZE_T <= SIZEOF_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(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), &(new), sizeof(void*), NULL)
      35             : # define accel_xlat_get(old, new)       zend_hash_index_find(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), (void**)&(new))
      36             : #else
      37             : # define accel_xlat_set(old, new)       zend_hash_quick_add(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new), sizeof(void*), NULL)
      38             : # define accel_xlat_get(old, new)       zend_hash_quick_find(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new))
      39             : #endif
      40             : 
      41             : typedef int (*id_function_t)(void *, void *);
      42             : typedef void (*unique_copy_ctor_func_t)(void *pElement);
      43             : 
      44             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
      45             : static const Bucket *uninitialized_bucket = NULL;
      46             : #endif
      47             : 
      48             : static int zend_prepare_function_for_execution(zend_op_array *op_array);
      49             : static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind);
      50             : 
      51           0 : static void zend_accel_destroy_zend_function(zend_function *function)
      52             : {
      53             :         TSRMLS_FETCH();
      54             : 
      55           0 :         if (function->type == ZEND_USER_FUNCTION) {
      56           0 :                 if (function->op_array.static_variables) {
      57             : 
      58           0 :                         efree(function->op_array.static_variables);
      59           0 :                         function->op_array.static_variables = NULL;
      60             :                 }
      61             :         }
      62             : 
      63           0 :         destroy_zend_function(function TSRMLS_CC);
      64           0 : }
      65             : 
      66           0 : static void zend_accel_destroy_zend_class(zend_class_entry **pce)
      67             : {
      68           0 :         zend_class_entry *ce = *pce;
      69             : 
      70           0 :         ce->function_table.pDestructor = (dtor_func_t) zend_accel_destroy_zend_function;
      71           0 :         destroy_zend_class(pce);
      72           0 : }
      73             : 
      74           0 : zend_persistent_script* create_persistent_script(void)
      75             : {
      76           0 :         zend_persistent_script *persistent_script = (zend_persistent_script *) emalloc(sizeof(zend_persistent_script));
      77           0 :         memset(persistent_script, 0, sizeof(zend_persistent_script));
      78             : 
      79           0 :         zend_hash_init(&persistent_script->function_table, 100, NULL, (dtor_func_t) zend_accel_destroy_zend_function, 0);
      80             :         /* class_table is usually destroyed by free_persistent_script() that
      81             :          * overrides destructor. ZEND_CLASS_DTOR may be used by standard
      82             :          * PHP compiler
      83             :          */
      84           0 :         zend_hash_init(&persistent_script->class_table, 10, NULL, ZEND_CLASS_DTOR, 0);
      85             : 
      86           0 :         return persistent_script;
      87             : }
      88             : 
      89           0 : static int compact_hash_table(HashTable *ht)
      90             : {
      91           0 :         uint i = 3;
      92             :         uint nSize;
      93             :         Bucket **t;
      94             : 
      95           0 :         if (!ht->nNumOfElements) {
      96             :                 /* Empty tables don't allocate space for Buckets */
      97           0 :                 return 1;
      98             :         }
      99             : 
     100           0 :         if (ht->nNumOfElements >= 0x80000000) {
     101             :                 /* prevent overflow */
     102           0 :                 nSize = 0x80000000;
     103             :         } else {
     104           0 :                 while ((1U << i) < ht->nNumOfElements) {
     105           0 :                         i++;
     106             :                 }
     107           0 :                 nSize = 1 << i;
     108             :         }
     109             : 
     110           0 :         if (nSize >= ht->nTableSize) {
     111             :                 /* Keep the size */
     112           0 :                 return 1;
     113             :         }
     114             : 
     115           0 :         t = (Bucket **)pemalloc(nSize * sizeof(Bucket *), ht->persistent);
     116           0 :         if (!t) {
     117           0 :                 return 0;
     118             :         }
     119             : 
     120           0 :         pefree(ht->arBuckets, ht->persistent);
     121             : 
     122           0 :         ht->arBuckets = t;
     123           0 :         ht->nTableSize = nSize;
     124           0 :         ht->nTableMask = ht->nTableSize - 1;
     125           0 :         zend_hash_rehash(ht);
     126             :         
     127           0 :         return 1;
     128             : }
     129             : 
     130           0 : int compact_persistent_script(zend_persistent_script *persistent_script)
     131             : {
     132           0 :         return compact_hash_table(&persistent_script->function_table) &&
     133           0 :                compact_hash_table(&persistent_script->class_table);
     134             : }
     135             : 
     136           0 : void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements)
     137             : {
     138           0 :         if (destroy_elements) {
     139           0 :                 persistent_script->function_table.pDestructor = (dtor_func_t)zend_accel_destroy_zend_function;
     140           0 :                 persistent_script->class_table.pDestructor = (dtor_func_t)zend_accel_destroy_zend_class;
     141             :         } else {
     142           0 :                 persistent_script->function_table.pDestructor = NULL;
     143           0 :                 persistent_script->class_table.pDestructor = NULL;
     144             :         }
     145             : 
     146           0 :         zend_hash_destroy(&persistent_script->function_table);
     147           0 :         zend_hash_destroy(&persistent_script->class_table);
     148             : 
     149           0 :         if (persistent_script->full_path) {
     150           0 :                 efree(persistent_script->full_path);
     151             :         }
     152             : 
     153           0 :         efree(persistent_script);
     154           0 : }
     155             : 
     156           0 : static int is_not_internal_function(zend_function *function)
     157             : {
     158           0 :         return(function->type != ZEND_INTERNAL_FUNCTION);
     159             : }
     160             : 
     161           0 : void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC)
     162             : {
     163           0 :         dtor_func_t orig_dtor = ht->pDestructor;
     164             : 
     165           0 :         ht->pDestructor = NULL;
     166           0 :         zend_hash_apply(ht, (apply_func_t) is_not_internal_function TSRMLS_CC);
     167           0 :         ht->pDestructor = orig_dtor;
     168           0 : }
     169             : 
     170           0 : static int move_user_function(zend_function *function
     171             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
     172             :         TSRMLS_DC 
     173             : #endif
     174             :         , int num_args, va_list args, zend_hash_key *hash_key) 
     175             : {
     176           0 :         HashTable *function_table = va_arg(args, HashTable *);
     177             :         (void)num_args; /* keep the compiler happy */
     178             : #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
     179             :         TSRMLS_FETCH();
     180             : #endif 
     181             : 
     182           0 :         if (function->type == ZEND_USER_FUNCTION) {
     183           0 :                 zend_hash_quick_update(function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, function, sizeof(zend_function), NULL);
     184           0 :                 return 1;
     185             :         } else {
     186           0 :                 return 0;
     187             :         }
     188             : }
     189             : 
     190           0 : void zend_accel_move_user_functions(HashTable *src, HashTable *dst TSRMLS_DC)
     191             : {
     192           0 :         dtor_func_t orig_dtor = src->pDestructor;
     193             : 
     194           0 :         src->pDestructor = NULL;
     195             : #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
     196             :         zend_hash_apply_with_arguments(src, (apply_func_args_t)move_user_function, 1, dst);
     197             : #else
     198           0 :         zend_hash_apply_with_arguments(src TSRMLS_CC, (apply_func_args_t)move_user_function, 1, dst);
     199             : #endif 
     200           0 :         src->pDestructor = orig_dtor;
     201           0 : }
     202             : 
     203           0 : static int copy_internal_function(zend_function *function, HashTable *function_table TSRMLS_DC)
     204             : {
     205           0 :         if (function->type == ZEND_INTERNAL_FUNCTION) {
     206           0 :                 zend_hash_update(function_table, function->common.function_name, strlen(function->common.function_name) + 1, function, sizeof(zend_function), NULL);
     207             :         }
     208           0 :         return 0;
     209             : }
     210             : 
     211           0 : void zend_accel_copy_internal_functions(TSRMLS_D)
     212             : {
     213           0 :         zend_hash_apply_with_argument(CG(function_table), (apply_func_arg_t)copy_internal_function, &ZCG(function_table) TSRMLS_CC);
     214           0 :         ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table));
     215           0 : }
     216             : 
     217           0 : static void zend_destroy_property_info(zend_property_info *property_info)
     218             : {
     219           0 :         interned_efree((char*)property_info->name);
     220           0 :         if (property_info->doc_comment) {
     221           0 :                 efree((char*)property_info->doc_comment);
     222             :         }
     223           0 : }
     224             : 
     225             : #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
     226           0 : static zend_ast *zend_ast_clone(zend_ast *ast TSRMLS_DC)
     227             : {
     228             :         int i;
     229             :         zend_ast *node;
     230             : 
     231           0 :         if (ast->kind == ZEND_CONST) {
     232           0 :                 node = emalloc(sizeof(zend_ast) + sizeof(zval));
     233           0 :                 node->kind = ZEND_CONST;
     234           0 :                 node->children = 0;
     235           0 :                 node->u.val = (zval*)(node + 1);
     236           0 :                 *node->u.val = *ast->u.val;
     237           0 :                 if ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
     238           0 :                         switch ((Z_TYPE_P(ast->u.val) & IS_CONSTANT_TYPE_MASK)) {
     239             :                                 case IS_STRING:
     240             :                             case IS_CONSTANT:
     241           0 :                                         Z_STRVAL_P(node->u.val) = (char *) interned_estrndup(Z_STRVAL_P(ast->u.val), Z_STRLEN_P(ast->u.val));
     242           0 :                                         break;
     243             :                                 case IS_ARRAY:
     244             :                             case IS_CONSTANT_ARRAY:
     245           0 :                                         if (ast->u.val->value.ht && ast->u.val->value.ht != &EG(symbol_table)) {
     246           0 :                                                 ALLOC_HASHTABLE(node->u.val->value.ht);
     247           0 :                                                 zend_hash_clone_zval(node->u.val->value.ht, ast->u.val->value.ht, 0);
     248             :                                         }
     249           0 :                                         break;
     250             :                             case IS_CONSTANT_AST:
     251           0 :                                 Z_AST_P(node->u.val) = zend_ast_clone(Z_AST_P(ast->u.val) TSRMLS_CC);
     252             :                                 break;
     253             :                         }
     254             :                 }
     255             :         } else {
     256           0 :                 node = emalloc(sizeof(zend_ast) + sizeof(zend_ast*) * (ast->children - 1));
     257           0 :                 node->kind = ast->kind;
     258           0 :                 node->children = ast->children;
     259           0 :                 for (i = 0; i < ast->children; i++) {
     260           0 :                         if ((&ast->u.child)[i]) {
     261           0 :                                 (&node->u.child)[i] = zend_ast_clone((&ast->u.child)[i] TSRMLS_CC);
     262             :                         } else {
     263           0 :                                 (&node->u.child)[i] = NULL;
     264             :                         }
     265             :                 }
     266             :         }
     267           0 :         return node;
     268             : }
     269             : #endif
     270             : 
     271           0 : static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC)
     272             : {
     273           0 :         zval *ret, **ret_ptr = NULL;
     274             : 
     275           0 :         if (!bind) {
     276           0 :                 ALLOC_ZVAL(ret);
     277           0 :                 *ret = *src;
     278           0 :                 INIT_PZVAL(ret);
     279           0 :         } else if (Z_REFCOUNT_P(src) == 1) {
     280           0 :                 ALLOC_ZVAL(ret);
     281           0 :                 *ret = *src;
     282           0 :         } else if (accel_xlat_get(src, ret_ptr) != SUCCESS) {
     283           0 :                 ALLOC_ZVAL(ret);
     284           0 :                 *ret = *src;
     285           0 :                 accel_xlat_set(src, ret);
     286             :         } else {
     287           0 :                 return *ret_ptr;
     288             :         }
     289             : 
     290             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
     291           0 :         if ((Z_TYPE_P(ret) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
     292           0 :                 switch ((Z_TYPE_P(ret) & IS_CONSTANT_TYPE_MASK)) {
     293             : #else
     294             :         if ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) {
     295             :                 switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) {
     296             : #endif
     297             :                         case IS_STRING:
     298             :                     case IS_CONSTANT:
     299           0 :                                 Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRLEN_P(ret));
     300           0 :                                 break;
     301             :                         case IS_ARRAY:
     302             :                     case IS_CONSTANT_ARRAY:
     303           0 :                                 if (ret->value.ht && ret->value.ht != &EG(symbol_table)) {
     304           0 :                                         ALLOC_HASHTABLE(ret->value.ht);
     305           0 :                                         zend_hash_clone_zval(ret->value.ht, src->value.ht, 0);
     306             :                                 }
     307           0 :                                 break;
     308             : #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
     309             :                     case IS_CONSTANT_AST:
     310           0 :                         Z_AST_P(ret) = zend_ast_clone(Z_AST_P(ret) TSRMLS_CC);
     311             :                         break;
     312             : #endif
     313             :                 }
     314             :         }
     315           0 :         return ret;
     316             : }
     317             : 
     318           0 : static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
     319             : {
     320             :         Bucket *p, *q, **prev;
     321             :         ulong nIndex;
     322             :         zval *ppz;
     323             :         TSRMLS_FETCH();
     324             : 
     325           0 :         ht->nTableSize = source->nTableSize;
     326           0 :         ht->nTableMask = source->nTableMask;
     327           0 :         ht->nNumOfElements = source->nNumOfElements;
     328           0 :         ht->nNextFreeElement = source->nNextFreeElement;
     329           0 :         ht->pDestructor = ZVAL_PTR_DTOR;
     330             : #if ZEND_DEBUG
     331             :         ht->inconsistent = 0;
     332             : #endif
     333           0 :         ht->persistent = 0;
     334           0 :         ht->arBuckets = NULL;
     335           0 :         ht->pListHead = NULL;
     336           0 :         ht->pListTail = NULL;
     337           0 :         ht->pInternalPointer = NULL;
     338           0 :         ht->nApplyCount = 0;
     339           0 :         ht->bApplyProtection = 1;
     340             : 
     341             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     342           0 :         if (!ht->nTableMask) {
     343           0 :                 ht->arBuckets = (Bucket**)&uninitialized_bucket;
     344           0 :                 return;
     345             :         }
     346             : #endif
     347             : 
     348           0 :         ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
     349             : 
     350           0 :         prev = &ht->pListHead;
     351           0 :         p = source->pListHead;
     352           0 :         while (p) {
     353           0 :                 nIndex = p->h & ht->nTableMask;
     354             : 
     355             :                 /* Create bucket and initialize key */
     356             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     357           0 :                 if (!p->nKeyLength) {
     358           0 :                         q = (Bucket *) emalloc(sizeof(Bucket));
     359           0 :                         q->arKey = NULL;
     360           0 :                 } else if (IS_INTERNED(p->arKey)) {
     361           0 :                         q = (Bucket *) emalloc(sizeof(Bucket));
     362           0 :                         q->arKey = p->arKey;
     363             :                 } else {
     364           0 :                         q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
     365           0 :                         q->arKey = ((char*)q) + sizeof(Bucket);
     366           0 :                         memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
     367             :                 }
     368             : #else
     369             :                 q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
     370             :                 if (p->nKeyLength) {
     371             :                         memcpy(q->arKey, p->arKey, p->nKeyLength);
     372             :                 }
     373             : #endif
     374           0 :                 q->h = p->h;
     375           0 :                 q->nKeyLength = p->nKeyLength;
     376             : 
     377             :                 /* Insert into hash collision list */
     378           0 :                 q->pNext = ht->arBuckets[nIndex];
     379           0 :                 q->pLast = NULL;
     380           0 :                 if (q->pNext) {
     381           0 :                         q->pNext->pLast = q;
     382             :                 }
     383           0 :                 ht->arBuckets[nIndex] = q;
     384             : 
     385             :                 /* Insert into global list */
     386           0 :                 q->pListLast = ht->pListTail;
     387           0 :                 ht->pListTail = q;
     388           0 :                 q->pListNext = NULL;
     389           0 :                 *prev = q;
     390           0 :                 prev = &q->pListNext;
     391             : 
     392             :                 /* Copy data */
     393           0 :                 q->pData = &q->pDataPtr;
     394           0 :                 if (!bind) {
     395           0 :                         ALLOC_ZVAL(ppz);
     396           0 :                         *ppz = *((zval*)p->pDataPtr);
     397           0 :                         INIT_PZVAL(ppz);
     398           0 :                 } else if (Z_REFCOUNT_P((zval*)p->pDataPtr) == 1) {
     399           0 :                         ALLOC_ZVAL(ppz);
     400           0 :                         *ppz = *((zval*)p->pDataPtr);
     401           0 :                 } else if (accel_xlat_get(p->pDataPtr, ppz) != SUCCESS) {
     402           0 :                         ALLOC_ZVAL(ppz);
     403           0 :                         *ppz = *((zval*)p->pDataPtr);
     404           0 :                         accel_xlat_set(p->pDataPtr, ppz);
     405             :                 } else {
     406           0 :                         q->pDataPtr = *(void**)ppz;
     407           0 :                         p = p->pListNext;
     408           0 :                         continue;
     409             :                 }
     410           0 :                 q->pDataPtr = (void*)ppz;
     411             : 
     412             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
     413           0 :                 if ((Z_TYPE_P((zval*)p->pDataPtr) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
     414           0 :                         switch ((Z_TYPE_P((zval*)p->pDataPtr) & IS_CONSTANT_TYPE_MASK)) {
     415             : #else
     416             :                 if ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) {
     417             :                         switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) {
     418             : #endif
     419             :                                 case IS_STRING:
     420             :                             case IS_CONSTANT:
     421           0 :                                         Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRLEN_P((zval*)p->pDataPtr));
     422           0 :                                         break;
     423             :                                 case IS_ARRAY:
     424             :                             case IS_CONSTANT_ARRAY:
     425           0 :                                         if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) {
     426           0 :                                                 ALLOC_HASHTABLE(ppz->value.ht);
     427           0 :                                                 zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0);
     428             :                                         }
     429           0 :                                         break;
     430             : #if ZEND_EXTENSION_API_NO > PHP_5_5_X_API_NO
     431             :                             case IS_CONSTANT_AST:
     432           0 :                                 Z_AST_P(ppz) = zend_ast_clone(Z_AST_P(ppz) TSRMLS_CC);
     433             :                                 break;
     434             : #endif
     435             :                         }
     436             :                 }
     437             : 
     438           0 :                 p = p->pListNext;
     439             :         }
     440           0 :         ht->pInternalPointer = ht->pListHead;
     441             : }
     442             : 
     443           0 : static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
     444             : {
     445             :         Bucket *p, *q, **prev;
     446             :         ulong nIndex;
     447             :         zend_class_entry **new_ce;
     448             :         zend_function** new_prototype;
     449             :         zend_op_array *new_entry;
     450             : 
     451           0 :         ht->nTableSize = source->nTableSize;
     452           0 :         ht->nTableMask = source->nTableMask;
     453           0 :         ht->nNumOfElements = source->nNumOfElements;
     454           0 :         ht->nNextFreeElement = source->nNextFreeElement;
     455           0 :         ht->pDestructor = ZEND_FUNCTION_DTOR;
     456             : #if ZEND_DEBUG
     457             :         ht->inconsistent = 0;
     458             : #endif
     459           0 :         ht->persistent = 0;
     460           0 :         ht->pListHead = NULL;
     461           0 :         ht->pListTail = NULL;
     462           0 :         ht->pInternalPointer = NULL;
     463           0 :         ht->nApplyCount = 0;
     464           0 :         ht->bApplyProtection = 1;
     465             : 
     466             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     467           0 :         if (!ht->nTableMask) {
     468           0 :                 ht->arBuckets = (Bucket**)&uninitialized_bucket;
     469           0 :                 return;
     470             :         }
     471             : #endif
     472             : 
     473           0 :         ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
     474             : 
     475           0 :         prev = &ht->pListHead;
     476           0 :         p = source->pListHead;
     477           0 :         while (p) {
     478           0 :                 nIndex = p->h & ht->nTableMask;
     479             : 
     480             :                 /* Create bucket and initialize key */
     481             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     482           0 :                 if (!p->nKeyLength) {
     483           0 :                         q = (Bucket *) emalloc(sizeof(Bucket));
     484           0 :                         q->arKey = NULL;
     485           0 :                 } else if (IS_INTERNED(p->arKey)) {
     486           0 :                         q = (Bucket *) emalloc(sizeof(Bucket));
     487           0 :                         q->arKey = p->arKey;
     488             :                 } else {
     489           0 :                         q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
     490           0 :                         q->arKey = ((char*)q) + sizeof(Bucket);
     491           0 :                         memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
     492             :                 }
     493             : #else
     494             :                 q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
     495             :                 if (p->nKeyLength) {
     496             :                         memcpy(q->arKey, p->arKey, p->nKeyLength);
     497             :                 }
     498             : #endif
     499           0 :                 q->h = p->h;
     500           0 :                 q->nKeyLength = p->nKeyLength;
     501             : 
     502             :                 /* Insert into hash collision list */
     503           0 :                 q->pNext = ht->arBuckets[nIndex];
     504           0 :                 q->pLast = NULL;
     505           0 :                 if (q->pNext) {
     506           0 :                         q->pNext->pLast = q;
     507             :                 }
     508           0 :                 ht->arBuckets[nIndex] = q;
     509             : 
     510             :                 /* Insert into global list */
     511           0 :                 q->pListLast = ht->pListTail;
     512           0 :                 ht->pListTail = q;
     513           0 :                 q->pListNext = NULL;
     514           0 :                 *prev = q;
     515           0 :                 prev = &q->pListNext;
     516             : 
     517             :                 /* Copy data */
     518           0 :                 q->pData = (void *) emalloc(sizeof(zend_function));
     519           0 :                 new_entry = (zend_op_array*)q->pData;
     520           0 :                 *new_entry = *(zend_op_array*)p->pData;
     521           0 :                 q->pDataPtr = NULL;
     522             : 
     523             :                 /* Copy constructor */
     524             :                 /* we use refcount to show that op_array is referenced from several places */
     525           0 :                 if (new_entry->refcount != NULL) {
     526           0 :                         accel_xlat_set(p->pData, new_entry);
     527             :                 }
     528             : 
     529           0 :                 zend_prepare_function_for_execution(new_entry);
     530             : 
     531           0 :                 if (old_ce == new_entry->scope) {
     532           0 :                         new_entry->scope = ce;
     533             :                 } else {
     534           0 :                         if (accel_xlat_get(new_entry->scope, new_ce) == SUCCESS) {
     535           0 :                                 new_entry->scope = *new_ce;
     536             :                         } else {
     537           0 :                                 zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
     538             :                         }
     539             :                 }
     540             : 
     541             :                 /* update prototype */
     542           0 :                 if (new_entry->prototype) {
     543           0 :                         if (accel_xlat_get(new_entry->prototype, new_prototype) == SUCCESS) {
     544           0 :                                 new_entry->prototype = *new_prototype;
     545             :                         } else {
     546           0 :                                 zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
     547             :                         }
     548             :                 }
     549             : 
     550           0 :                 p = p->pListNext;
     551             :         }
     552           0 :         ht->pInternalPointer = ht->pListHead;
     553             : }
     554             : 
     555           0 : static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
     556             : {
     557             :         Bucket *p, *q, **prev;
     558             :         ulong nIndex;
     559             :         zend_class_entry **new_ce;
     560             :         zend_property_info *prop_info;
     561             : 
     562           0 :         ht->nTableSize = source->nTableSize;
     563           0 :         ht->nTableMask = source->nTableMask;
     564           0 :         ht->nNumOfElements = source->nNumOfElements;
     565           0 :         ht->nNextFreeElement = source->nNextFreeElement;
     566           0 :         ht->pDestructor = (dtor_func_t) zend_destroy_property_info;
     567             : #if ZEND_DEBUG
     568             :         ht->inconsistent = 0;
     569             : #endif
     570           0 :         ht->persistent = 0;
     571           0 :         ht->pListHead = NULL;
     572           0 :         ht->pListTail = NULL;
     573           0 :         ht->pInternalPointer = NULL;
     574           0 :         ht->nApplyCount = 0;
     575           0 :         ht->bApplyProtection = 1;
     576             : 
     577             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     578           0 :         if (!ht->nTableMask) {
     579           0 :                 ht->arBuckets = (Bucket**)&uninitialized_bucket;
     580           0 :                 return;
     581             :         }
     582             : #endif
     583             : 
     584           0 :         ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
     585             : 
     586           0 :         prev = &ht->pListHead;
     587           0 :         p = source->pListHead;
     588           0 :         while (p) {
     589           0 :                 nIndex = p->h & ht->nTableMask;
     590             : 
     591             :                 /* Create bucket and initialize key */
     592             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     593           0 :                 if (!p->nKeyLength) {
     594           0 :                         q = (Bucket *) emalloc(sizeof(Bucket));
     595           0 :                         q->arKey = NULL;
     596           0 :                 } else if (IS_INTERNED(p->arKey)) {
     597           0 :                         q = (Bucket *) emalloc(sizeof(Bucket));
     598           0 :                         q->arKey = p->arKey;
     599             :                 } else {
     600           0 :                         q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
     601           0 :                         q->arKey = ((char*)q) + sizeof(Bucket);
     602           0 :                         memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
     603             :                 }
     604             : #else
     605             :                 q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
     606             :                 if (p->nKeyLength) {
     607             :                         memcpy(q->arKey, p->arKey, p->nKeyLength);
     608             :                 }
     609             : #endif
     610           0 :                 q->h = p->h;
     611           0 :                 q->nKeyLength = p->nKeyLength;
     612             : 
     613             :                 /* Insert into hash collision list */
     614           0 :                 q->pNext = ht->arBuckets[nIndex];
     615           0 :                 q->pLast = NULL;
     616           0 :                 if (q->pNext) {
     617           0 :                         q->pNext->pLast = q;
     618             :                 }
     619           0 :                 ht->arBuckets[nIndex] = q;
     620             : 
     621             :                 /* Insert into global list */
     622           0 :                 q->pListLast = ht->pListTail;
     623           0 :                 ht->pListTail = q;
     624           0 :                 q->pListNext = NULL;
     625           0 :                 *prev = q;
     626           0 :                 prev = &q->pListNext;
     627             : 
     628             :                 /* Copy data */
     629           0 :                 q->pData = (void *) emalloc(sizeof(zend_property_info));
     630           0 :                 prop_info = q->pData;
     631           0 :                 *prop_info = *(zend_property_info*)p->pData;
     632           0 :                 q->pDataPtr = NULL;
     633             : 
     634             :                 /* Copy constructor */
     635           0 :                 prop_info->name = interned_estrndup(prop_info->name, prop_info->name_length);
     636           0 :                 if (prop_info->doc_comment) {
     637           0 :                         if (ZCG(accel_directives).load_comments) {
     638           0 :                                 prop_info->doc_comment = estrndup(prop_info->doc_comment, prop_info->doc_comment_len);
     639             :                         } else {
     640           0 :                                 prop_info->doc_comment = NULL;
     641             :                         }
     642             :                 }
     643           0 :                 if (prop_info->ce == old_ce) {
     644           0 :                         prop_info->ce = ce;
     645           0 :                 } else if (accel_xlat_get(prop_info->ce, new_ce) == SUCCESS) {
     646           0 :                         prop_info->ce = *new_ce;
     647             :                 } else {
     648           0 :                         zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name, prop_info->name);
     649             :                 }
     650             : 
     651           0 :                 p = p->pListNext;
     652             :         }
     653           0 :         ht->pInternalPointer = ht->pListHead;
     654             : }
     655             : 
     656             : /* protects reference count, creates copy of statics */
     657           0 : static int zend_prepare_function_for_execution(zend_op_array *op_array)
     658             : {
     659           0 :         HashTable *shared_statics = op_array->static_variables;
     660             : 
     661             :         /* protect reference count */
     662           0 :         op_array->refcount = &zend_accel_refcount;
     663           0 :         (*op_array->refcount) = ZEND_PROTECTED_REFCOUNT;
     664             : 
     665             :         /* copy statics */
     666           0 :         if (shared_statics) {
     667           0 :                 ALLOC_HASHTABLE(op_array->static_variables);
     668           0 :                 zend_hash_clone_zval(op_array->static_variables, shared_statics, 0);
     669             :         }
     670             : 
     671           0 :         return 0;
     672             : }
     673             : 
     674             : #define zend_update_inherited_handler(handler) \
     675             : { \
     676             :         if (ce->handler != NULL) { \
     677             :                 if (accel_xlat_get(ce->handler, new_func) == SUCCESS) { \
     678             :                         ce->handler = *new_func; \
     679             :                 } else { \
     680             :                         zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name); \
     681             :                 } \
     682             :         } \
     683             : }
     684             : 
     685             : /* Protects class' refcount, copies default properties, functions and class name */
     686           0 : static void zend_class_copy_ctor(zend_class_entry **pce)
     687             : {
     688           0 :         zend_class_entry *ce = *pce;
     689           0 :         zend_class_entry *old_ce = ce;
     690             :         zend_class_entry **new_ce;
     691             :         zend_function **new_func;
     692             :         TSRMLS_FETCH();
     693             : 
     694           0 :         *pce = ce = emalloc(sizeof(zend_class_entry));
     695           0 :         *ce = *old_ce;
     696           0 :         ce->refcount = 1;
     697             : 
     698           0 :         if (old_ce->refcount != 1) {
     699             :                 /* this class is not used as a parent for any other classes */
     700           0 :                 accel_xlat_set(old_ce, ce);
     701             :         }
     702             : 
     703             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     704           0 :         if (old_ce->default_properties_table) {
     705             :                 int i;
     706             : 
     707           0 :                 ce->default_properties_table = emalloc(sizeof(zval*) * old_ce->default_properties_count);
     708           0 :                 for (i = 0; i < old_ce->default_properties_count; i++) {
     709           0 :                         if (old_ce->default_properties_table[i]) {
     710           0 :                                 ce->default_properties_table[i] = zend_clone_zval(old_ce->default_properties_table[i], 0 TSRMLS_CC);
     711             :                         } else {
     712           0 :                                 ce->default_properties_table[i] = NULL;
     713             :                         }
     714             :                 }
     715             :         }
     716             : #else
     717             :         zend_hash_clone_zval(&ce->default_properties, &old_ce->default_properties, 0);
     718             : #endif
     719             : 
     720           0 :         zend_hash_clone_methods(&ce->function_table, &old_ce->function_table, old_ce, ce TSRMLS_CC);
     721             : 
     722             :         /* static members */
     723             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     724           0 :         if (old_ce->default_static_members_table) {
     725             :                 int i;
     726             : 
     727           0 :                 ce->default_static_members_table = emalloc(sizeof(zval*) * old_ce->default_static_members_count);
     728           0 :                 for (i = 0; i < old_ce->default_static_members_count; i++) {
     729           0 :                         if (old_ce->default_static_members_table[i]) {
     730           0 :                                 ce->default_static_members_table[i] = zend_clone_zval(old_ce->default_static_members_table[i], 1 TSRMLS_CC);
     731             :                         } else {
     732           0 :                                 ce->default_static_members_table[i] = NULL;
     733             :                         }
     734             :                 }
     735             :         }
     736           0 :         ce->static_members_table = ce->default_static_members_table;
     737             : #else
     738             :         zend_hash_clone_zval(&ce->default_static_members, &old_ce->default_static_members, 1);
     739             :         ce->static_members = &ce->default_static_members;
     740             : #endif
     741             : 
     742             :         /* properties_info */
     743           0 :         zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce, ce TSRMLS_CC);
     744             : 
     745             :         /* constants table */
     746           0 :         zend_hash_clone_zval(&ce->constants_table, &old_ce->constants_table, 0);
     747             : 
     748           0 :         ce->name = interned_estrndup(ce->name, ce->name_length);
     749             : 
     750             :         /* interfaces aren't really implemented, so we create a new table */
     751           0 :         if (ce->num_interfaces) {
     752           0 :                 ce->interfaces = emalloc(sizeof(zend_class_entry *) * ce->num_interfaces);
     753           0 :                 memset(ce->interfaces, 0, sizeof(zend_class_entry *) * ce->num_interfaces);
     754             :         } else {
     755           0 :                 ce->interfaces = NULL;
     756             :         }
     757           0 :         if (ZEND_CE_DOC_COMMENT(ce)) {
     758           0 :                 if (ZCG(accel_directives).load_comments) {
     759           0 :                         ZEND_CE_DOC_COMMENT(ce) = estrndup(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce));
     760             :                 } else {
     761           0 :                         ZEND_CE_DOC_COMMENT(ce) =  NULL;
     762             :                 }
     763             :         }
     764             : 
     765           0 :         if (ce->parent) {
     766           0 :                 if (accel_xlat_get(ce->parent, new_ce) == SUCCESS) {
     767           0 :                         ce->parent = *new_ce;
     768             :                 } else {
     769           0 :                         zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name);
     770             :                 }
     771             :         }
     772             : 
     773           0 :         zend_update_inherited_handler(constructor);
     774           0 :         zend_update_inherited_handler(destructor);
     775           0 :         zend_update_inherited_handler(clone);
     776           0 :         zend_update_inherited_handler(__get);
     777           0 :         zend_update_inherited_handler(__set);
     778           0 :         zend_update_inherited_handler(__call);
     779             : /* 5.1 stuff */
     780           0 :         zend_update_inherited_handler(serialize_func);
     781           0 :         zend_update_inherited_handler(unserialize_func);
     782           0 :         zend_update_inherited_handler(__isset);
     783           0 :         zend_update_inherited_handler(__unset);
     784             : /* 5.2 stuff */
     785           0 :         zend_update_inherited_handler(__tostring);
     786             : 
     787             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
     788             : /* 5.3 stuff */
     789           0 :         zend_update_inherited_handler(__callstatic);
     790             : #endif
     791             : 
     792             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     793             : /* 5.4 traits */
     794           0 :         if (ce->trait_aliases) {
     795             :                 zend_trait_alias **trait_aliases;
     796           0 :                 int i = 0;
     797             : 
     798           0 :                 while (ce->trait_aliases[i]) {
     799           0 :                         i++;
     800             :                 }
     801           0 :                 trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1));
     802           0 :                 i = 0;
     803           0 :                 while (ce->trait_aliases[i]) {
     804           0 :                         trait_aliases[i] = emalloc(sizeof(zend_trait_alias));
     805           0 :                         memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias));
     806           0 :                         trait_aliases[i]->trait_method = emalloc(sizeof(zend_trait_method_reference));
     807           0 :                         memcpy(trait_aliases[i]->trait_method, ce->trait_aliases[i]->trait_method, sizeof(zend_trait_method_reference));
     808           0 :                         if (trait_aliases[i]->trait_method) {
     809           0 :                                 if (trait_aliases[i]->trait_method->method_name) {
     810           0 :                                         trait_aliases[i]->trait_method->method_name =
     811           0 :                                                 estrndup(trait_aliases[i]->trait_method->method_name,
     812             :                                                         trait_aliases[i]->trait_method->mname_len);
     813             :                                 }
     814           0 :                                 if (trait_aliases[i]->trait_method->class_name) {
     815           0 :                                         trait_aliases[i]->trait_method->class_name =
     816           0 :                                                 estrndup(trait_aliases[i]->trait_method->class_name,
     817             :                                                         trait_aliases[i]->trait_method->cname_len);
     818             :                                 }
     819             :                         }
     820             : 
     821           0 :                         if (trait_aliases[i]->alias) {
     822           0 :                                 trait_aliases[i]->alias =
     823           0 :                                         estrndup(trait_aliases[i]->alias,
     824             :                                                 trait_aliases[i]->alias_len);
     825             :                         }
     826           0 :                         i++;
     827             :                 }
     828           0 :                 trait_aliases[i] = NULL;
     829           0 :                 ce->trait_aliases = trait_aliases;
     830             :         }
     831             : 
     832           0 :         if (ce->trait_precedences) {
     833             :                 zend_trait_precedence **trait_precedences;
     834           0 :                 int i = 0;
     835             : 
     836           0 :                 while (ce->trait_precedences[i]) {
     837           0 :                         i++;
     838             :                 }
     839           0 :                 trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1));
     840           0 :                 i = 0;
     841           0 :                 while (ce->trait_precedences[i]) {
     842           0 :                         trait_precedences[i] = emalloc(sizeof(zend_trait_precedence));
     843           0 :                         memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence));
     844           0 :                         trait_precedences[i]->trait_method = emalloc(sizeof(zend_trait_method_reference));
     845           0 :                         memcpy(trait_precedences[i]->trait_method, ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference));
     846             : 
     847           0 :                         trait_precedences[i]->trait_method->method_name =
     848           0 :                                 estrndup(trait_precedences[i]->trait_method->method_name,
     849             :                                         trait_precedences[i]->trait_method->mname_len);
     850           0 :                         trait_precedences[i]->trait_method->class_name =
     851           0 :                                 estrndup(trait_precedences[i]->trait_method->class_name,
     852             :                                         trait_precedences[i]->trait_method->cname_len);
     853             : 
     854           0 :                         if (trait_precedences[i]->exclude_from_classes) {
     855             :                                 zend_class_entry **exclude_from_classes;
     856           0 :                                 int j = 0;
     857             : 
     858           0 :                                 while (trait_precedences[i]->exclude_from_classes[j]) {
     859           0 :                                         j++;
     860             :                                 }
     861           0 :                                 exclude_from_classes = emalloc(sizeof(zend_class_entry*) * (j + 1));
     862           0 :                                 j = 0;
     863           0 :                                 while (trait_precedences[i]->exclude_from_classes[j]) {
     864           0 :                                         exclude_from_classes[j] = (zend_class_entry*)estrndup(
     865             :                                                 (char*)trait_precedences[i]->exclude_from_classes[j],
     866             :                                                 strlen((char*)trait_precedences[i]->exclude_from_classes[j]));
     867           0 :                                         j++;
     868             :                                 }
     869           0 :                                 exclude_from_classes[j] = NULL;
     870           0 :                                 trait_precedences[i]->exclude_from_classes = exclude_from_classes;
     871             :                         }
     872           0 :                         i++;
     873             :                 }
     874           0 :                 trait_precedences[i] = NULL;
     875           0 :                 ce->trait_precedences = trait_precedences;
     876             :         }
     877             : #endif
     878           0 : }
     879             : 
     880           0 : static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor, uint size, int ignore_dups, void **fail_data, void **conflict_data)
     881             : {
     882             :         Bucket *p;
     883             :         void *t;
     884             : 
     885           0 :         p = source->pListHead;
     886           0 :         while (p) {
     887           0 :                 if (p->nKeyLength > 0) {
     888           0 :                         if (zend_hash_quick_add(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
     889           0 :                                 if (pCopyConstructor) {
     890           0 :                                         pCopyConstructor(t);
     891             :                                 }
     892             :                         } else {
     893           0 :                                 if (p->nKeyLength > 0 && p->arKey[0] == 0) {
     894             :                                         /* Mangled key */
     895             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
     896           0 :                                         if (((zend_function*)p->pData)->common.fn_flags & ZEND_ACC_CLOSURE) {
     897             :                                                 /* update closure */
     898           0 :                                                 if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
     899           0 :                                                         if (pCopyConstructor) {
     900           0 :                                                                 pCopyConstructor(t);
     901             :                                                         }
     902             :                                                 }
     903             :                                         } else {
     904             :                                                 /* ignore and wait for runtime */
     905             :                                         } 
     906             : #endif
     907           0 :                                 } else if (!ignore_dups && zend_hash_quick_find(target, p->arKey, p->nKeyLength, p->h, &t) == SUCCESS) {
     908           0 :                                         *fail_data = p->pData;
     909           0 :                                         *conflict_data = t;
     910           0 :                                         return FAILURE;
     911             :                                 }
     912             :                         }
     913             :                 } else {
     914           0 :                         if (!zend_hash_index_exists(target, p->h) && zend_hash_index_update(target, p->h, p->pData, size, &t) == SUCCESS) {
     915           0 :                                 if (pCopyConstructor) {
     916           0 :                                         pCopyConstructor(t);
     917             :                                 }
     918           0 :                         } else if (!ignore_dups && zend_hash_index_find(target,p->h, &t) == SUCCESS) {
     919           0 :                                 *fail_data = p->pData;
     920           0 :                                 *conflict_data = t;
     921           0 :                                 return FAILURE;
     922             :                         }
     923             :                 }
     924           0 :                 p = p->pListNext;
     925             :         }
     926           0 :         target->pInternalPointer = target->pListHead;
     927             : 
     928           0 :         return SUCCESS;
     929             : }
     930             : 
     931           0 : static void zend_accel_function_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor)
     932             : {
     933             :         zend_function *function1, *function2;
     934             :         TSRMLS_FETCH();
     935             : 
     936           0 :         if (zend_hash_unique_copy(target, source, pCopyConstructor, sizeof(zend_function), 0, (void**)&function1, (void**)&function2) != SUCCESS) {
     937           0 :                 CG(in_compilation) = 1;
     938           0 :                 zend_set_compiled_filename(function1->op_array.filename TSRMLS_CC);
     939           0 :                 CG(zend_lineno) = function1->op_array.opcodes[0].lineno;
     940           0 :                 if (function2->type == ZEND_USER_FUNCTION
     941           0 :                         && function2->op_array.last > 0) {
     942           0 :                         zend_error(E_ERROR, "Cannot redeclare %s() (previously declared in %s:%d)",
     943           0 :                                            function1->common.function_name,
     944           0 :                                            function2->op_array.filename,
     945           0 :                                            (int)function2->op_array.opcodes[0].lineno);
     946             :                 } else {
     947           0 :                         zend_error(E_ERROR, "Cannot redeclare %s()", function1->common.function_name);
     948             :                 }
     949             :         }
     950           0 : }
     951             : 
     952           0 : static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor TSRMLS_DC)
     953             : {
     954             :         zend_class_entry **pce1, **pce2;
     955             : 
     956           0 :         if (zend_hash_unique_copy(target, source, pCopyConstructor, sizeof(zend_class_entry*), ZCG(accel_directives).ignore_dups, (void**)&pce1, (void**)&pce2) != SUCCESS) {
     957           0 :                 CG(in_compilation) = 1;
     958             : #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
     959           0 :                 zend_set_compiled_filename((*pce1)->info.user.filename TSRMLS_CC);
     960           0 :                 CG(zend_lineno) = (*pce1)->info.user.line_start;
     961             : #else
     962             :                 zend_set_compiled_filename((*pce1)->filename TSRMLS_CC);
     963             :                 CG(zend_lineno) = (*pce1)->line_start;
     964             : #endif
     965           0 :                 zend_error(E_ERROR, "Cannot redeclare class %s", (*pce1)->name);
     966             :         }
     967           0 : }
     968             : 
     969             : #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
     970             : static void zend_do_delayed_early_binding(zend_op_array *op_array, zend_uint early_binding TSRMLS_DC)
     971             : {
     972             :         zend_uint opline_num = early_binding;
     973             : 
     974             :         if ((int)opline_num != -1) {
     975             :                 zend_bool orig_in_compilation = CG(in_compilation);
     976             :                 char *orig_compiled_filename = zend_set_compiled_filename(op_array->filename TSRMLS_CC);
     977             :                 zend_class_entry **pce;
     978             : 
     979             :                 CG(in_compilation) = 1;
     980             :                 while ((int)opline_num != -1) {
     981             :                         if (zend_lookup_class(Z_STRVAL(op_array->opcodes[opline_num - 1].op2.u.constant), Z_STRLEN(op_array->opcodes[opline_num - 1].op2.u.constant), &pce TSRMLS_CC) == SUCCESS) {
     982             :                                 do_bind_inherited_class(&op_array->opcodes[opline_num], EG(class_table), *pce, 1 TSRMLS_CC);
     983             :                         }
     984             :                         opline_num = op_array->opcodes[opline_num].result.u.opline_num;
     985             :                 }
     986             :                 zend_restore_compiled_filename(orig_compiled_filename TSRMLS_CC);
     987             :                 CG(in_compilation) = orig_in_compilation;
     988             :         }
     989             : }
     990             : #endif
     991             : 
     992           0 : zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory TSRMLS_DC)
     993             : {
     994             :         zend_op_array *op_array;
     995             : 
     996           0 :         op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
     997           0 :         *op_array = persistent_script->main_op_array;
     998             : 
     999           0 :         if (from_shared_memory) {
    1000             :                 /* Copy all the necessary stuff from shared memory to regular memory, and protect the shared script */
    1001           0 :                 if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
    1002           0 :                         zend_hash_init(&ZCG(bind_hash), 10, NULL, NULL, 0);
    1003           0 :                         zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, (unique_copy_ctor_func_t) zend_class_copy_ctor TSRMLS_CC);
    1004           0 :                         zend_hash_destroy(&ZCG(bind_hash));
    1005             :                 }
    1006             :                 /* we must first to copy all classes and then prepare functions, since functions may try to bind
    1007             :                    classes - which depend on pre-bind class entries existent in the class table */
    1008           0 :                 if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
    1009           0 :                         zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table, (unique_copy_ctor_func_t)zend_prepare_function_for_execution);
    1010             :                 }
    1011             : 
    1012           0 :                 zend_prepare_function_for_execution(op_array);
    1013             : 
    1014             :                 /* Register __COMPILER_HALT_OFFSET__ constant */
    1015           0 :                 if (persistent_script->compiler_halt_offset != 0 &&
    1016           0 :                     persistent_script->full_path) {
    1017             :                         char *name, *cfilename;
    1018           0 :                         char haltoff[] = "__COMPILER_HALT_OFFSET__";
    1019             :                         int len, clen;
    1020             : 
    1021           0 :                         cfilename = persistent_script->full_path;
    1022           0 :                         clen = strlen(cfilename);
    1023           0 :                         zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0);
    1024           0 :                         if (!zend_hash_exists(EG(zend_constants), name, len + 1)) {
    1025           0 :                                 zend_register_long_constant(name, len + 1, persistent_script->compiler_halt_offset, CONST_CS, 0 TSRMLS_CC);
    1026             :                         }
    1027           0 :                         efree(name);
    1028             :                 }
    1029             : 
    1030             : #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
    1031             :                 if ((int)persistent_script->early_binding != -1) {
    1032             :                         zend_do_delayed_early_binding(op_array, persistent_script->early_binding TSRMLS_CC);
    1033             :                 }
    1034             : #endif
    1035             : 
    1036             :         } else /* if (!from_shared_memory) */ {
    1037           0 :                 if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
    1038           0 :                         zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table, NULL);
    1039             :                 }
    1040           0 :                 if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
    1041           0 :                         zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, NULL TSRMLS_CC);
    1042             :                 }
    1043           0 :                 free_persistent_script(persistent_script, 0); /* free only hashes */
    1044             :         }
    1045             : 
    1046             : #if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
    1047           0 :         if (op_array->early_binding != (zend_uint)-1) {
    1048           0 :                 char *orig_compiled_filename = CG(compiled_filename);
    1049           0 :                 CG(compiled_filename) = persistent_script->full_path;
    1050           0 :                 zend_do_delayed_early_binding(op_array TSRMLS_CC);
    1051           0 :                 CG(compiled_filename) = orig_compiled_filename;
    1052             :         }
    1053             : #endif
    1054             : 
    1055           0 :         return op_array;
    1056             : }
    1057             : 
    1058             : /*
    1059             :  * zend_adler32() is based on zlib implementation
    1060             :  * Computes the Adler-32 checksum of a data stream
    1061             :  *
    1062             :  * Copyright (C) 1995-2005 Mark Adler
    1063             :  * For conditions of distribution and use, see copyright notice in zlib.h
    1064             :  *
    1065             :  * Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
    1066             :  *
    1067             :  *  This software is provided 'as-is', without any express or implied
    1068             :  *  warranty.  In no event will the authors be held liable for any damages
    1069             :  *  arising from the use of this software.
    1070             :  *
    1071             :  *  Permission is granted to anyone to use this software for any purpose,
    1072             :  *  including commercial applications, and to alter it and redistribute it
    1073             :  *  freely, subject to the following restrictions:
    1074             :  *
    1075             :  *  1. The origin of this software must not be misrepresented; you must not
    1076             :  *     claim that you wrote the original software. If you use this software
    1077             :  *     in a product, an acknowledgment in the product documentation would be
    1078             :  *     appreciated but is not required.
    1079             :  *  2. Altered source versions must be plainly marked as such, and must not be
    1080             :  *     misrepresented as being the original software.
    1081             :  *  3. This notice may not be removed or altered from any source distribution.
    1082             :  *
    1083             :  */
    1084             : 
    1085             : #define ADLER32_BASE 65521 /* largest prime smaller than 65536 */
    1086             : #define ADLER32_NMAX 5552
    1087             : /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
    1088             : 
    1089             : #define ADLER32_DO1(buf)        {s1 += *(buf); s2 += s1;}
    1090             : #define ADLER32_DO2(buf, i)     ADLER32_DO1(buf + i); ADLER32_DO1(buf + i + 1);
    1091             : #define ADLER32_DO4(buf, i)     ADLER32_DO2(buf, i); ADLER32_DO2(buf, i + 2);
    1092             : #define ADLER32_DO8(buf, i)     ADLER32_DO4(buf, i); ADLER32_DO4(buf, i + 4);
    1093             : #define ADLER32_DO16(buf)       ADLER32_DO8(buf, 0); ADLER32_DO8(buf, 8);
    1094             : 
    1095           0 : unsigned int zend_adler32(unsigned int checksum, signed char *buf, uint len)
    1096             : {
    1097           0 :         unsigned int s1 = checksum & 0xffff;
    1098           0 :         unsigned int s2 = (checksum >> 16) & 0xffff;
    1099             :         signed char *end;
    1100             : 
    1101           0 :         while (len >= ADLER32_NMAX) {
    1102           0 :                 len -= ADLER32_NMAX;
    1103           0 :                 end = buf + ADLER32_NMAX;
    1104             :                 do {
    1105           0 :                         ADLER32_DO16(buf);
    1106           0 :                         buf += 16;
    1107           0 :                 } while (buf != end);
    1108           0 :                 s1 %= ADLER32_BASE;
    1109           0 :                 s2 %= ADLER32_BASE;
    1110             :         }
    1111             : 
    1112           0 :         if (len) {
    1113           0 :                 if (len >= 16) {
    1114           0 :                         end = buf + (len & 0xfff0);
    1115           0 :                         len &= 0xf;
    1116             :                         do {
    1117           0 :                                 ADLER32_DO16(buf);
    1118           0 :                                 buf += 16;
    1119           0 :                         } while (buf != end);
    1120             :                 }
    1121           0 :                 if (len) {
    1122           0 :                         end = buf + len;
    1123             :                         do {
    1124           0 :                                 ADLER32_DO1(buf);
    1125           0 :                                 buf++;
    1126           0 :                         } while (buf != end);
    1127             :                 }
    1128           0 :                 s1 %= ADLER32_BASE;
    1129           0 :                 s2 %= ADLER32_BASE;
    1130             :         }
    1131             : 
    1132           0 :         return (s2 << 16) | s1;
    1133             : }

Generated by: LCOV version 1.10

Generated at Sun, 06 Apr 2014 17:31:05 +0000 (9 days ago)

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