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

LTP GCOV extension - code coverage report
Current view: directory - var/php_gcov/PHP_5_3/Zend - zend_execute.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 604
Code covered: 82.9 % Executed lines: 501
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2009 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16                 :    |          Zeev Suraski <zeev@zend.com>                                |
      17                 :    +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: zend_execute.c 281670 2009-06-04 18:20:45Z mattwil $ */
      21                 : 
      22                 : #define ZEND_INTENSIVE_DEBUGGING 0
      23                 : 
      24                 : #include <stdio.h>
      25                 : #include <signal.h>
      26                 : 
      27                 : #include "zend.h"
      28                 : #include "zend_compile.h"
      29                 : #include "zend_execute.h"
      30                 : #include "zend_API.h"
      31                 : #include "zend_ptr_stack.h"
      32                 : #include "zend_constants.h"
      33                 : #include "zend_extensions.h"
      34                 : #include "zend_ini.h"
      35                 : #include "zend_exceptions.h"
      36                 : #include "zend_interfaces.h"
      37                 : #include "zend_closures.h"
      38                 : #include "zend_vm.h"
      39                 : 
      40                 : /* Virtual current working directory support */
      41                 : #include "tsrm_virtual_cwd.h"
      42                 : 
      43                 : #define _CONST_CODE  0
      44                 : #define _TMP_CODE    1
      45                 : #define _VAR_CODE    2
      46                 : #define _UNUSED_CODE 3
      47                 : #define _CV_CODE     4
      48                 : 
      49                 : typedef int (*incdec_t)(zval *);
      50                 : 
      51                 : #define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free, type TSRMLS_CC)
      52                 : #define get_zval_ptr_ptr(node, Ts, should_free, type) _get_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC)
      53                 : #define get_obj_zval_ptr(node, Ts, should_free, type) _get_obj_zval_ptr(node, Ts, should_free, type TSRMLS_CC)
      54                 : #define get_obj_zval_ptr_ptr(node, Ts, should_free, type) _get_obj_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC)
      55                 : 
      56                 : /* Prototypes */
      57                 : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
      58                 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
      59                 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
      60                 : 
      61                 : #define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED))
      62                 : 
      63                 : #define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
      64                 : #define T(offset) (*(temp_variable *)((char *) Ts + offset))
      65                 : 
      66                 : #define TEMP_VAR_STACK_LIMIT 2000
      67                 : 
      68                 : static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *should_free, int unref TSRMLS_DC)
      69        27864611 : {
      70        27864611 :         if (!Z_DELREF_P(z)) {
      71        15223575 :                 Z_SET_REFCOUNT_P(z, 1);
      72        15223575 :                 Z_UNSET_ISREF_P(z);
      73        15223575 :                 should_free->var = z;
      74                 : /*              should_free->is_var = 1; */
      75                 :         } else {
      76        12641036 :                 should_free->var = 0;
      77        12641036 :                 if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) {
      78           26163 :                         Z_UNSET_ISREF_P(z);
      79                 :                 }
      80        12641036 :                 GC_ZVAL_CHECK_POSSIBLE_ROOT(z);
      81                 :         }
      82        27864611 : }
      83                 : 
      84                 : static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
      85            5575 : {
      86            5575 :         if (!Z_DELREF_P(z)) {
      87               2 :                 if (z != &EG(uninitialized_zval)) {
      88               2 :                         GC_REMOVE_ZVAL_FROM_BUFFER(z);
      89               2 :                         zval_dtor(z);
      90               2 :                         efree(z);
      91                 :                 }
      92                 :         }
      93            5575 : }
      94                 : 
      95                 : #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC)
      96                 : #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)
      97                 : #define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC)
      98                 : #define PZVAL_LOCK(z) Z_ADDREF_P((z))
      99                 : #define RETURN_VALUE_UNUSED(pzn)        (((pzn)->u.EA.type & EXT_TYPE_UNUSED))
     100                 : #define SELECTIVE_PZVAL_LOCK(pzv, pzn)  if (!RETURN_VALUE_UNUSED(pzn)) { PZVAL_LOCK(pzv); }
     101                 : 
     102                 : #define AI_USE_PTR(ai) \
     103                 :         if ((ai).ptr_ptr) { \
     104                 :                 (ai).ptr = *((ai).ptr_ptr); \
     105                 :                 (ai).ptr_ptr = &((ai).ptr); \
     106                 :         } else { \
     107                 :                 (ai).ptr = NULL; \
     108                 :         }
     109                 : 
     110                 : #define AI_SET_PTR(ai, val)             \
     111                 :         (ai).ptr = (val);                       \
     112                 :         (ai).ptr_ptr = &((ai).ptr);
     113                 : 
     114                 : #define FREE_OP(should_free) \
     115                 :         if (should_free.var) { \
     116                 :                 if ((zend_uintptr_t)should_free.var & 1L) { \
     117                 :                         zval_dtor((zval*)((zend_uintptr_t)should_free.var & ~1L)); \
     118                 :                 } else { \
     119                 :                         zval_ptr_dtor(&should_free.var); \
     120                 :                 } \
     121                 :         }
     122                 : 
     123                 : #define FREE_OP_IF_VAR(should_free) \
     124                 :         if (should_free.var != NULL && (((zend_uintptr_t)should_free.var & 1L) == 0)) { \
     125                 :                 zval_ptr_dtor(&should_free.var); \
     126                 :         }
     127                 : 
     128                 : #define FREE_OP_VAR_PTR(should_free) \
     129                 :         if (should_free.var) { \
     130                 :                 zval_ptr_dtor(&should_free.var); \
     131                 :         }
     132                 : 
     133                 : #define TMP_FREE(z) (zval*)(((zend_uintptr_t)(z)) | 1L)
     134                 : 
     135                 : #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)
     136                 : 
     137                 : #define INIT_PZVAL_COPY(z,v) \
     138                 :         (z)->value = (v)->value; \
     139                 :         Z_TYPE_P(z) = Z_TYPE_P(v); \
     140                 :         Z_SET_REFCOUNT_P(z, 1); \
     141                 :         Z_UNSET_ISREF_P(z);
     142                 : 
     143                 : #define MAKE_REAL_ZVAL_PTR(val) \
     144                 :         do { \
     145                 :                 zval *_tmp; \
     146                 :                 ALLOC_ZVAL(_tmp); \
     147                 :                 _tmp->value = (val)->value; \
     148                 :                 Z_TYPE_P(_tmp) = Z_TYPE_P(val); \
     149                 :                 Z_SET_REFCOUNT_P(_tmp, 1); \
     150                 :                 Z_UNSET_ISREF_P(_tmp); \
     151                 :                 val = _tmp; \
     152                 :         } while (0)
     153                 : 
     154                 : /* End of zend_execute_locks.h */
     155                 : 
     156                 : #define CV_OF(i)     (EG(current_execute_data)->CVs[i])
     157                 : #define CV_DEF_OF(i) (EG(active_op_array)->vars[i])
     158                 : 
     159                 : #define CTOR_CALL_BIT    0x1
     160                 : #define CTOR_USED_BIT    0x2
     161                 : 
     162                 : #define IS_CTOR_CALL(ce) (((zend_uintptr_t)(ce)) & CTOR_CALL_BIT)
     163                 : #define IS_CTOR_USED(ce) (((zend_uintptr_t)(ce)) & CTOR_USED_BIT)
     164                 : 
     165                 : #define ENCODE_CTOR(ce, used) \
     166                 :         ((zend_class_entry*)(((zend_uintptr_t)(ce)) | CTOR_CALL_BIT | ((used) ? CTOR_USED_BIT : 0)))
     167                 : #define DECODE_CTOR(ce) \
     168                 :         ((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT)))
     169                 : 
     170                 : ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var)
     171               0 : {
     172               0 :         return execute_data_ptr->CVs[var];
     173                 : }
     174                 : 
     175                 : static zend_always_inline zval *_get_zval_ptr_tmp(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
     176        22487851 : {
     177        22487851 :         return should_free->var = &T(node->u.var).tmp_var;
     178                 : }
     179                 : 
     180                 : static zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
     181            5560 : {
     182            5560 :         temp_variable *T = &T(node->u.var);
     183            5560 :         zval *str = T->str_offset.str;
     184                 :         zval *ptr;
     185                 : 
     186                 :         /* string offset */
     187            5560 :         ALLOC_ZVAL(ptr);
     188            5560 :         T->str_offset.ptr = ptr;
     189            5560 :         should_free->var = ptr;
     190                 : 
     191            5578 :         if (T->str_offset.str->type != IS_STRING
     192                 :                 || ((int)T->str_offset.offset < 0)
     193                 :                 || (T->str_offset.str->value.str.len <= (int)T->str_offset.offset)) {
     194              18 :                 ptr->value.str.val = STR_EMPTY_ALLOC();
     195              18 :                 ptr->value.str.len = 0;
     196                 :         } else {
     197            5542 :                 ptr->value.str.val = estrndup(str->value.str.val + T->str_offset.offset, 1);
     198            5542 :                 ptr->value.str.len = 1;
     199                 :         }
     200            5560 :         PZVAL_UNLOCK_FREE(str);
     201            5560 :         Z_SET_REFCOUNT_P(ptr, 1);
     202            5560 :         Z_SET_ISREF_P(ptr);
     203            5560 :         ptr->type = IS_STRING;
     204            5560 :         return ptr;
     205                 : }
     206                 : 
     207                 : static zend_always_inline zval *_get_zval_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
     208        22668658 : {
     209        22668658 :         zval *ptr = T(node->u.var).var.ptr;
     210        22668658 :         if (EXPECTED(ptr != NULL)) {
     211        22663098 :                 PZVAL_UNLOCK(ptr, should_free);
     212        22663098 :                 return ptr;
     213                 :         } else {
     214            5560 :                 return _get_zval_ptr_var_string_offset(node, Ts, should_free TSRMLS_CC);
     215                 :         }
     216                 : }
     217                 : 
     218                 : static zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)
     219         5382335 : {
     220         5382335 :         zend_compiled_variable *cv = &CV_DEF_OF(var);
     221                 : 
     222         5382335 :         if (!EG(active_symbol_table) ||
     223                 :             zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
     224         5370559 :                 switch (type) {
     225                 :                         case BP_VAR_R:
     226                 :                         case BP_VAR_UNSET:
     227             581 :                                 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
     228                 :                                 /* break missing intentionally */
     229                 :                         case BP_VAR_IS:
     230             583 :                                 return &EG(uninitialized_zval_ptr);
     231                 :                                 break;
     232                 :                         case BP_VAR_RW:
     233               3 :                                 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
     234                 :                                 /* break missing intentionally */
     235                 :                         case BP_VAR_W:
     236         5369976 :                                 Z_ADDREF(EG(uninitialized_zval));
     237         5369976 :                                 if (!EG(active_symbol_table)) {
     238         4835106 :                                         *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
     239         4835106 :                                         **ptr = &EG(uninitialized_zval);
     240                 :                                 } else {
     241          534870 :                                         zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
     242                 :                                 }
     243                 :                                 break;
     244                 :                 }
     245                 :         }
     246         5381752 :         return *ptr;
     247                 : }
     248                 : 
     249                 : static zend_always_inline zval *_get_zval_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC)
     250        39106047 : {
     251        39106047 :         zval ***ptr = &CV_OF(node->u.var);
     252                 : 
     253        39106047 :         if (UNEXPECTED(*ptr == NULL)) {
     254           11352 :                 return *_get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);
     255                 :         }
     256        39094695 :         return **ptr;
     257                 : }
     258                 : 
     259                 : static inline zval *_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
     260         3177209 : {
     261                 : /*      should_free->is_var = 0; */
     262         3177209 :         switch (node->op_type) {
     263                 :                 case IS_CONST:
     264          343326 :                         should_free->var = 0;
     265          343326 :                         return &node->u.constant;
     266                 :                         break;
     267                 :                 case IS_TMP_VAR:
     268         1161391 :                         should_free->var = TMP_FREE(&T(node->u.var).tmp_var);
     269         1161391 :                         return &T(node->u.var).tmp_var;
     270                 :                         break;
     271                 :                 case IS_VAR:
     272          120088 :                         return _get_zval_ptr_var(node, Ts, should_free TSRMLS_CC);
     273                 :                         break;
     274                 :                 case IS_UNUSED:
     275               0 :                         should_free->var = 0;
     276               0 :                         return NULL;
     277                 :                         break;
     278                 :                 case IS_CV:
     279         1552404 :                         should_free->var = 0;
     280         1552404 :                         return _get_zval_ptr_cv(node, Ts, type TSRMLS_CC);
     281                 :                         break;
     282                 :                 EMPTY_SWITCH_DEFAULT_CASE()
     283                 :         }
     284               0 :         return NULL;
     285                 : }
     286                 : 
     287                 : static zend_always_inline zval **_get_zval_ptr_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
     288         5201429 : {
     289         5201429 :         zval** ptr_ptr = T(node->u.var).var.ptr_ptr;
     290                 : 
     291         5201429 :         if (EXPECTED(ptr_ptr != NULL)) {
     292         5201315 :                 PZVAL_UNLOCK(*ptr_ptr, should_free);
     293                 :         } else {
     294                 :                 /* string offset */
     295             114 :                 PZVAL_UNLOCK(T(node->u.var).str_offset.str, should_free);
     296                 :         }
     297         5201429 :         return ptr_ptr;
     298                 : }
     299                 : 
     300                 : static zend_always_inline zval **_get_zval_ptr_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC)
     301        32667497 : {
     302        32667497 :         zval ***ptr = &CV_OF(node->u.var);
     303                 : 
     304        32667497 :         if (UNEXPECTED(*ptr == NULL)) {
     305         5370983 :                 return _get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);
     306                 :         }
     307        27296514 :         return *ptr;
     308                 : }
     309                 : 
     310                 : static inline zval **_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
     311         3134141 : {
     312         3134141 :         if (node->op_type == IS_CV) {
     313         3134140 :                 should_free->var = 0;
     314         3134140 :                 return _get_zval_ptr_ptr_cv(node, Ts, type TSRMLS_CC);
     315               1 :         } else if (node->op_type == IS_VAR) {
     316               1 :                 return _get_zval_ptr_ptr_var(node, Ts, should_free TSRMLS_CC);
     317                 :         } else {
     318               0 :                 should_free->var = 0;
     319               0 :                 return NULL;
     320                 :         }
     321                 : }
     322                 : 
     323                 : static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D)
     324           31017 : {
     325           31017 :         if (EXPECTED(EG(This) != NULL)) {
     326           31016 :                 return EG(This);
     327                 :         } else {
     328               1 :                 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     329                 :                 return NULL;
     330                 :         }
     331                 : }
     332                 : 
     333                 : static inline zval **_get_obj_zval_ptr_ptr(const znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
     334               0 : {
     335               0 :         if (op->op_type == IS_UNUSED) {
     336               0 :                 if (EXPECTED(EG(This) != NULL)) {
     337                 :                         /* this should actually never be modified, _ptr_ptr is modified only when
     338                 :                            the object is empty */
     339               0 :                         should_free->var = 0;
     340               0 :                         return &EG(This);
     341                 :                 } else {
     342               0 :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     343                 :                 }
     344                 :         }
     345               0 :         return get_zval_ptr_ptr(op, Ts, should_free, type);
     346                 : }
     347                 : 
     348                 : static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
     349            9106 : {
     350            9106 :         if (EXPECTED(EG(This) != NULL)) {
     351            9105 :                 return &EG(This);
     352                 :         } else {
     353               1 :                 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     354                 :                 return NULL;
     355                 :         }
     356                 : }
     357                 : 
     358                 : static inline zval *_get_obj_zval_ptr(znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
     359               0 : {
     360               0 :         if (op->op_type == IS_UNUSED) {
     361               0 :                 if (EXPECTED(EG(This) != NULL)) {
     362               0 :                         should_free->var = 0;
     363               0 :                         return EG(This);
     364                 :                 } else {
     365               0 :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     366                 :                 }
     367                 :         }
     368               0 :         return get_zval_ptr(op, Ts, should_free, type);
     369                 : }
     370                 : 
     371                 : static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC)
     372           54947 : {
     373           54947 :         if (T->var.ptr) {
     374           54932 :                 if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */
     375           54674 :                         Z_DELREF_P(T->var.ptr);
     376                 :                 }
     377           54932 :                 zval_ptr_dtor(&T->var.ptr);
     378              15 :         } else if (!T->var.ptr_ptr) {
     379                 :                 /* perform the equivalent of equivalent of a
     380                 :                  * quick & silent get_zval_ptr, and FREE_OP
     381                 :                  */
     382              15 :                 PZVAL_UNLOCK_FREE(T->str_offset.str);
     383                 :         }
     384           54947 : }
     385                 : 
     386                 : static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)
     387          591649 : {
     388          591649 :         zval *variable_ptr = *variable_ptr_ptr;
     389          591649 :         zval *value_ptr = *value_ptr_ptr;
     390                 : 
     391          591660 :         if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
     392              11 :                 variable_ptr_ptr = &EG(uninitialized_zval_ptr);
     393          591638 :         } else if (variable_ptr != value_ptr) {
     394          580691 :                 if (!PZVAL_IS_REF(value_ptr)) {
     395                 :                         /* break it away */
     396          411375 :                         Z_DELREF_P(value_ptr);
     397          411375 :                         if (Z_REFCOUNT_P(value_ptr)>0) {
     398              44 :                                 ALLOC_ZVAL(*value_ptr_ptr);
     399              44 :                                 **value_ptr_ptr = *value_ptr;
     400              44 :                                 value_ptr = *value_ptr_ptr;
     401              44 :                                 zendi_zval_copy_ctor(*value_ptr);
     402                 :                         }
     403          411375 :                         Z_SET_REFCOUNT_P(value_ptr, 1);
     404          411375 :                         Z_SET_ISREF_P(value_ptr);
     405                 :                 }
     406                 : 
     407          580691 :                 *variable_ptr_ptr = value_ptr;
     408          580691 :                 Z_ADDREF_P(value_ptr);
     409                 : 
     410          580691 :                 zval_ptr_dtor(&variable_ptr);
     411           10947 :         } else if (!Z_ISREF_P(variable_ptr)) {
     412             842 :                 if (variable_ptr_ptr == value_ptr_ptr) {
     413             580 :                         SEPARATE_ZVAL(variable_ptr_ptr);
     414             262 :                 } else if (variable_ptr==EG(uninitialized_zval_ptr)
     415                 :                         || Z_REFCOUNT_P(variable_ptr)>2) {
     416                 :                         /* we need to separate */
     417             260 :                         Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2);
     418             260 :                         ALLOC_ZVAL(*variable_ptr_ptr);
     419             260 :                         **variable_ptr_ptr = *variable_ptr;
     420             260 :                         zval_copy_ctor(*variable_ptr_ptr);
     421             260 :                         *value_ptr_ptr = *variable_ptr_ptr;
     422             260 :                         Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2);
     423                 :                 }
     424             842 :                 Z_SET_ISREF_PP(variable_ptr_ptr);
     425                 :         }
     426          591649 : }
     427                 : 
     428                 : /* this should modify object only if it's empty */
     429                 : static inline void make_real_object(zval **object_ptr TSRMLS_DC)
     430            4285 : {
     431            4285 :         if (Z_TYPE_PP(object_ptr) == IS_NULL
     432                 :                 || (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0)
     433                 :                 || (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0)
     434                 :         ) {
     435               6 :                 zend_error(E_STRICT, "Creating default object from empty value");
     436                 : 
     437               6 :                 SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
     438               6 :                 zval_dtor(*object_ptr);
     439               6 :                 object_init(*object_ptr);
     440                 :         }
     441            4285 : }
     442                 : 
     443                 : static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)
     444            1304 : {
     445            1304 :         *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
     446                 : 
     447            1304 :         *class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
     448            1304 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     449             586 :                 return "implement interface ";
     450                 :         } else {
     451             718 :                 return "be an instance of ";
     452                 :         }
     453                 : }
     454                 : 
     455                 : static inline int zend_verify_arg_error(const zend_function *zf, zend_uint arg_num, const zend_arg_info *cur_arg_info, const char *need_msg, const char *need_kind, const char *given_msg, char *given_kind TSRMLS_DC)
     456              34 : {
     457              34 :         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
     458              34 :         char *fname = zf->common.function_name;
     459                 :         char *fsep;
     460                 :         char *fclass;
     461                 : 
     462              34 :         if (zf->common.scope) {
     463              19 :                 fsep =  "::";
     464              19 :                 fclass = zf->common.scope->name;
     465                 :         } else {
     466              15 :                 fsep =  "";
     467              15 :                 fclass = "";
     468                 :         }
     469                 : 
     470              36 :         if (ptr && ptr->op_array) {
     471              18 :                 zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, ptr->opline->lineno);
     472                 :         } else {
     473              16 :                 zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
     474                 :         }
     475              12 :         return 0;
     476                 : }
     477                 : 
     478                 : static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC)
     479        29210697 : {
     480                 :         zend_arg_info *cur_arg_info;
     481                 :         char *need_msg;
     482                 :         zend_class_entry *ce;
     483                 : 
     484        29210697 :         if (!zf->common.arg_info
     485                 :                 || arg_num>zf->common.num_args) {
     486           90826 :                 return 1;
     487                 :         }
     488                 : 
     489        29119871 :         cur_arg_info = &zf->common.arg_info[arg_num-1];
     490                 : 
     491        29119871 :         if (cur_arg_info->class_name) {
     492                 :                 const char *class_name;
     493                 : 
     494            1319 :                 if (!arg) {
     495               2 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     496               2 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC);
     497                 :                 }
     498            1317 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     499            1290 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     500            1290 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
     501              12 :                                 return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
     502                 :                         }
     503              27 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
     504              12 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     505              12 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
     506                 :                 }
     507        29118552 :         } else if (cur_arg_info->array_type_hint) {
     508             374 :                 if (!arg) {
     509               2 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC);
     510                 :                 }
     511             372 :                 if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     512               6 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
     513                 :                 }
     514                 :         }
     515        29119837 :         return 1;
     516                 : }
     517                 : 
     518                 : static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval *property_name, znode *value_op, const temp_variable *Ts, int opcode TSRMLS_DC)
     519                 : 
     520           15617 : {
     521           15617 :         zval *object = *object_ptr;
     522                 :         zend_free_op free_value;
     523           15617 :         zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R);
     524           15617 :         zval **retval = &T(result->u.var).var.ptr;
     525                 : 
     526           15617 :         if (Z_TYPE_P(object) != IS_OBJECT) {
     527              24 :                 if (object == EG(error_zval_ptr)) {
     528               0 :                         if (!RETURN_VALUE_UNUSED(result)) {
     529               0 :                                 *retval = EG(uninitialized_zval_ptr);
     530               0 :                                 PZVAL_LOCK(*retval);
     531                 :                         }
     532               0 :                         FREE_OP(free_value);
     533               0 :                         return;
     534                 :                 }
     535              44 :                 if (Z_TYPE_P(object) == IS_NULL ||
     536                 :                     (Z_TYPE_P(object) == IS_BOOL && Z_LVAL_P(object) == 0) ||
     537                 :                     (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
     538              20 :                         SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
     539              20 :                         zval_dtor(*object_ptr);
     540              20 :                         object_init(*object_ptr);
     541              20 :                         object = *object_ptr;
     542              20 :                         zend_error(E_STRICT, "Creating default object from empty value");
     543                 :                 } else {
     544               4 :                         zend_error(E_WARNING, "Attempt to assign property of non-object");
     545               4 :                         if (!RETURN_VALUE_UNUSED(result)) {
     546               0 :                                 *retval = EG(uninitialized_zval_ptr);
     547               0 :                                 PZVAL_LOCK(*retval);
     548                 :                         }
     549               4 :                         FREE_OP(free_value);
     550               4 :                         return;
     551                 :                 }
     552                 :         }
     553                 :         
     554                 :         /* separate our value if necessary */
     555           15613 :         if (value_op->op_type == IS_TMP_VAR) {
     556             587 :                 zval *orig_value = value;
     557                 : 
     558             587 :                 ALLOC_ZVAL(value);
     559             587 :                 *value = *orig_value;
     560             587 :                 Z_UNSET_ISREF_P(value);
     561             587 :                 Z_SET_REFCOUNT_P(value, 0);
     562           15026 :         } else if (value_op->op_type == IS_CONST) {
     563            1226 :                 zval *orig_value = value;
     564                 : 
     565            1226 :                 ALLOC_ZVAL(value);
     566            1226 :                 *value = *orig_value;
     567            1226 :                 Z_UNSET_ISREF_P(value);
     568            1226 :                 Z_SET_REFCOUNT_P(value, 0);
     569            1226 :                 zval_copy_ctor(value);
     570                 :         }
     571                 : 
     572                 : 
     573           15613 :         Z_ADDREF_P(value);
     574           15613 :         if (opcode == ZEND_ASSIGN_OBJ) {
     575           15089 :                 if (!Z_OBJ_HT_P(object)->write_property) {
     576               0 :                         zend_error(E_WARNING, "Attempt to assign property of non-object");
     577               0 :                         if (!RETURN_VALUE_UNUSED(result)) {
     578               0 :                                 *retval = EG(uninitialized_zval_ptr);
     579               0 :                                 PZVAL_LOCK(*retval);
     580                 :                         }
     581               0 :                         if (value_op->op_type == IS_TMP_VAR) {
     582               0 :                                 FREE_ZVAL(value);
     583               0 :                         } else if (value_op->op_type == IS_CONST) {
     584               0 :                                 zval_ptr_dtor(&value);
     585                 :                         }
     586               0 :                         FREE_OP(free_value);
     587               0 :                         return;
     588                 :                 }
     589           15089 :                 Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);
     590                 :         } else {
     591                 :                 /* Note:  property_name in this case is really the array index! */
     592             524 :                 if (!Z_OBJ_HT_P(object)->write_dimension) {
     593               0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
     594                 :                 }
     595             524 :                 Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
     596                 :         }
     597                 : 
     598           15605 :         if (!RETURN_VALUE_UNUSED(result) && !EG(exception)) {
     599              29 :                 AI_SET_PTR(T(result->u.var).var, value);
     600              29 :                 PZVAL_LOCK(value);
     601                 :         }
     602           15605 :         zval_ptr_dtor(&value);
     603           15605 :         FREE_OP_IF_VAR(free_value);
     604                 : }
     605                 : 
     606                 : static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC)
     607             107 : {
     608             107 :         if (Z_TYPE_P(T->str_offset.str) == IS_STRING) {
     609                 : 
     610             107 :                 if (((int)T->str_offset.offset < 0)) {
     611               1 :                         zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
     612               1 :                         return 0;
     613                 :                 }
     614                 : 
     615             106 :                 if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
     616               3 :                         Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
     617               3 :                         memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
     618                 :                                ' ',
     619                 :                                T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
     620               3 :                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
     621               3 :                         Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
     622                 :                 }
     623                 : 
     624             106 :                 if (Z_TYPE_P(value) != IS_STRING) {
     625              11 :                         zval tmp = *value;
     626                 : 
     627              11 :                         if (value_type != IS_TMP_VAR) {
     628               8 :                                 zval_copy_ctor(&tmp);
     629                 :                         }
     630              11 :                         convert_to_string(&tmp);
     631              11 :                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL(tmp)[0];
     632              11 :                         STR_FREE(Z_STRVAL(tmp));
     633                 :                 } else {
     634              95 :                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(value)[0];
     635              95 :                         if (value_type == IS_TMP_VAR) {
     636                 :                                 /* we can safely free final_value here
     637                 :                                  * because separation is done only
     638                 :                                  * in case value_type == IS_VAR */
     639              10 :                                 STR_FREE(Z_STRVAL_P(value));
     640                 :                         }
     641                 :                 }
     642                 :                 /*
     643                 :                  * the value of an assignment to a string offset is undefined
     644                 :                 T(result->u.var).var = &T->str_offset.str;
     645                 :                 */
     646                 :         }
     647             106 :         return 1;
     648                 : }
     649                 : 
     650                 : static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value, int is_tmp_var TSRMLS_DC)
     651        15266854 : {
     652        15266854 :         zval *variable_ptr = *variable_ptr_ptr;
     653                 :         zval garbage;
     654                 : 
     655        15266854 :         if (variable_ptr == EG(error_zval_ptr)) {
     656              14 :                 if (is_tmp_var) {
     657               0 :                         zval_dtor(value);
     658                 :                 }
     659              14 :                 return EG(uninitialized_zval_ptr);
     660                 :         }
     661                 : 
     662        15266840 :         if (Z_TYPE_P(variable_ptr) == IS_OBJECT && Z_OBJ_HANDLER_P(variable_ptr, set)) {
     663               0 :                 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
     664               0 :                 return variable_ptr;
     665                 :         }
     666                 : 
     667        15266840 :         if (PZVAL_IS_REF(variable_ptr)) {
     668           14690 :                 if (variable_ptr!=value) {
     669           14689 :                         zend_uint refcount = Z_REFCOUNT_P(variable_ptr);
     670                 : 
     671           14689 :                         garbage = *variable_ptr;
     672           14689 :                         *variable_ptr = *value;
     673           14689 :                         Z_SET_REFCOUNT_P(variable_ptr, refcount);
     674           14689 :                         Z_SET_ISREF_P(variable_ptr);
     675           14689 :                         if (!is_tmp_var) {
     676           14371 :                                 zendi_zval_copy_ctor(*variable_ptr);
     677                 :                         }
     678           14689 :                         zendi_zval_dtor(garbage);
     679           14688 :                         return variable_ptr;
     680                 :                 }
     681                 :         } else {
     682        15252150 :                 if (Z_DELREF_P(variable_ptr)==0) {
     683         8801919 :                         if (!is_tmp_var) {
     684         6649106 :                                 if (variable_ptr==value) {
     685             153 :                                         Z_ADDREF_P(variable_ptr);
     686         6648953 :                                 } else if (PZVAL_IS_REF(value)) {
     687         1698848 :                                         garbage = *variable_ptr;
     688         1698848 :                                         *variable_ptr = *value;
     689         1698848 :                                         INIT_PZVAL(variable_ptr);
     690         1698848 :                                         zval_copy_ctor(variable_ptr);
     691         1698848 :                                         zendi_zval_dtor(garbage);
     692         1698845 :                                         return variable_ptr;
     693                 :                                 } else {
     694         4950105 :                                         Z_ADDREF_P(value);
     695         4950105 :                                         *variable_ptr_ptr = value;
     696         4950105 :                                         if (variable_ptr != &EG(uninitialized_zval)) {
     697         4950105 :                                                 GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
     698         4950105 :                                                 zval_dtor(variable_ptr);
     699         4950105 :                                                 efree(variable_ptr);
     700                 :                                         }
     701         4950105 :                                         return value;
     702                 :                                 }
     703                 :                         } else {
     704         2152813 :                                 garbage = *variable_ptr;
     705         2152813 :                                 *variable_ptr = *value;
     706         2152813 :                                 INIT_PZVAL(variable_ptr);
     707         2152813 :                                 zendi_zval_dtor(garbage);
     708         2152813 :                                 return variable_ptr;
     709                 :                         }
     710                 :                 } else { /* we need to split */
     711         6450231 :                         if (!is_tmp_var) {
     712         5138347 :                                 if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
     713          649641 :                                         ALLOC_ZVAL(variable_ptr);
     714          649641 :                                         *variable_ptr_ptr = variable_ptr;
     715          649641 :                                         *variable_ptr = *value;
     716          649641 :                                         zval_copy_ctor(variable_ptr);
     717          649641 :                                         Z_SET_REFCOUNT_P(variable_ptr, 1);
     718                 :                                 } else {
     719         3839065 :                                         *variable_ptr_ptr = value;
     720         3839065 :                                         Z_ADDREF_P(value);
     721                 :                                 }
     722                 :                         } else {
     723         1961525 :                                 ALLOC_ZVAL(*variable_ptr_ptr);
     724         1961525 :                                 Z_SET_REFCOUNT_P(value, 1);
     725         1961525 :                                 **variable_ptr_ptr = *value;
     726                 :                         }
     727                 :                 }
     728         6450384 :                 Z_UNSET_ISREF_PP(variable_ptr_ptr);
     729                 :         }
     730                 : 
     731         6450385 :         return *variable_ptr_ptr;
     732                 : }
     733                 : 
     734                 : 
     735                 : /* Utility Functions for Extensions */
     736                 : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     737               0 : {
     738               0 :         if (extension->statement_handler) {
     739               0 :                 extension->statement_handler(op_array);
     740                 :         }
     741               0 : }
     742                 : 
     743                 : 
     744                 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     745               0 : {
     746               0 :         if (extension->fcall_begin_handler) {
     747               0 :                 extension->fcall_begin_handler(op_array);
     748                 :         }
     749               0 : }
     750                 : 
     751                 : 
     752                 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     753               0 : {
     754               0 :         if (extension->fcall_end_handler) {
     755               0 :                 extension->fcall_end_handler(op_array);
     756                 :         }
     757               0 : }
     758                 : 
     759                 : 
     760                 : static inline HashTable *zend_get_target_symbol_table(const zend_op *opline, const temp_variable *Ts, int type, const zval *variable TSRMLS_DC)
     761         1561874 : {
     762         1561874 :         switch (opline->op2.u.EA.type) {
     763                 :                 case ZEND_FETCH_LOCAL:
     764         1005697 :                         if (!EG(active_symbol_table)) {
     765           29612 :                                 zend_rebuild_symbol_table(TSRMLS_C);
     766                 :                         }
     767         1005697 :                         return EG(active_symbol_table);
     768                 :                         break;
     769                 :                 case ZEND_FETCH_GLOBAL:
     770                 :                 case ZEND_FETCH_GLOBAL_LOCK:
     771          554879 :                         return &EG(symbol_table);
     772                 :                         break;
     773                 :                 case ZEND_FETCH_STATIC:
     774            1298 :                         if (!EG(active_op_array)->static_variables) {
     775               0 :                                 ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
     776               0 :                                 zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
     777                 :                         }
     778            1298 :                         return EG(active_op_array)->static_variables;
     779                 :                         break;
     780                 :                 EMPTY_SWITCH_DEFAULT_CASE()
     781                 :         }
     782               0 :         return NULL;
     783                 : }
     784                 : 
     785                 : static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int type TSRMLS_DC)
     786         6135282 : {
     787                 :         zval **retval;
     788                 :         char *offset_key;
     789                 :         int offset_key_length;
     790                 :         long index;
     791                 : 
     792         6135282 :         switch (dim->type) {
     793                 :                 case IS_NULL:
     794              10 :                         offset_key = "";
     795              10 :                         offset_key_length = 0;
     796              10 :                         goto fetch_string_dim;
     797                 : 
     798                 :                 case IS_STRING:
     799                 :                         
     800         3312248 :                         offset_key = dim->value.str.val;
     801         3312248 :                         offset_key_length = dim->value.str.len;
     802                 :                         
     803         3312258 : fetch_string_dim:
     804         3312258 :                         if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
     805         1574795 :                                 switch (type) {
     806                 :                                         case BP_VAR_R:
     807           99692 :                                                 zend_error(E_NOTICE, "Undefined index: %s", offset_key);
     808                 :                                                 /* break missing intentionally */
     809                 :                                         case BP_VAR_UNSET:
     810                 :                                         case BP_VAR_IS:
     811           99692 :                                                 retval = &EG(uninitialized_zval_ptr);
     812           99692 :                                                 break;
     813                 :                                         case BP_VAR_RW:
     814               1 :                                                 zend_error(E_NOTICE,"Undefined index: %s", offset_key);
     815                 :                                                 /* break missing intentionally */
     816                 :                                         case BP_VAR_W: {
     817         1475103 :                                                         zval *new_zval = &EG(uninitialized_zval);
     818                 : 
     819         1475103 :                                                         Z_ADDREF_P(new_zval);
     820         1475103 :                                                         zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval);
     821                 :                                                 }
     822                 :                                                 break;
     823                 :                                 }
     824                 :                         }
     825         3312258 :                         break;
     826                 :                 case IS_DOUBLE:
     827              51 :                         index = zend_dval_to_lval(Z_DVAL_P(dim));
     828              51 :                         goto num_index;
     829                 :                 case IS_RESOURCE:
     830               3 :                         zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
     831                 :                         /* Fall Through */
     832                 :                 case IS_BOOL:
     833                 :                 case IS_LONG:
     834         2822967 :                         index = Z_LVAL_P(dim);
     835         2823018 : num_index:
     836         2823018 :                         if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) {
     837          249381 :                                 switch (type) {
     838                 :                                         case BP_VAR_R:
     839              11 :                                                 zend_error(E_NOTICE,"Undefined offset: %ld", index);
     840                 :                                                 /* break missing intentionally */
     841                 :                                         case BP_VAR_UNSET:
     842                 :                                         case BP_VAR_IS:
     843              12 :                                                 retval = &EG(uninitialized_zval_ptr);
     844              12 :                                                 break;
     845                 :                                         case BP_VAR_RW:
     846               0 :                                                 zend_error(E_NOTICE,"Undefined offset: %ld", index);
     847                 :                                                 /* break missing intentionally */
     848                 :                                         case BP_VAR_W: {
     849          249369 :                                                 zval *new_zval = &EG(uninitialized_zval);
     850                 : 
     851          249369 :                                                 Z_ADDREF_P(new_zval);
     852          249369 :                                                 zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval);
     853                 :                                         }
     854                 :                                         break;
     855                 :                                 }
     856                 :                         }
     857         2823018 :                         break;
     858                 : 
     859                 :                 default:
     860               6 :                         zend_error(E_WARNING, "Illegal offset type");
     861               6 :                         return (type == BP_VAR_W || type == BP_VAR_RW) ?
     862                 :                                 &EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
     863                 :         }
     864         6135276 :         return retval;
     865                 : }
     866                 : 
     867                 : static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
     868         3438321 : {
     869         3438321 :         zval *container = *container_ptr;
     870                 :         zval **retval;
     871                 : 
     872         3438321 :         switch (Z_TYPE_P(container)) {
     873                 : 
     874                 :                 case IS_ARRAY:
     875         3437091 :                         if (type != BP_VAR_UNSET && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) {
     876           11402 :                                 SEPARATE_ZVAL(container_ptr);
     877           11402 :                                 container = *container_ptr;
     878                 :                         }
     879         3438145 : fetch_from_array:
     880         3438145 :                         if (dim == NULL) {
     881          256035 :                                 zval *new_zval = &EG(uninitialized_zval);
     882                 : 
     883          256035 :                                 Z_ADDREF_P(new_zval);
     884          256035 :                                 if (zend_hash_next_index_insert(Z_ARRVAL_P(container), &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) {
     885               1 :                                         zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
     886               1 :                                         retval = &EG(error_zval_ptr);
     887               1 :                                         Z_DELREF_P(new_zval);
     888                 :                                 }
     889                 :                         } else {
     890         3182110 :                                 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
     891                 :                         }
     892         3438145 :                         result->var.ptr_ptr = retval;
     893         3438145 :                         PZVAL_LOCK(*retval);
     894         3438145 :                         return;
     895                 :                         break;
     896                 : 
     897                 :                 case IS_NULL:
     898            1047 :                         if (container == EG(error_zval_ptr)) {
     899               1 :                                 result->var.ptr_ptr = &EG(error_zval_ptr);
     900               1 :                                 PZVAL_LOCK(EG(error_zval_ptr));
     901            1046 :                         } else if (type != BP_VAR_UNSET) {
     902            1054 : convert_to_array:
     903            1054 :                                 if (!PZVAL_IS_REF(container)) {
     904            1053 :                                         SEPARATE_ZVAL(container_ptr);
     905            1053 :                                         container = *container_ptr;
     906                 :                                 }
     907            1054 :                                 zval_dtor(container);
     908            1054 :                                 array_init(container);
     909            1054 :                                 goto fetch_from_array;
     910                 :                         } else {
     911                 :                                 /* for read-mode only */
     912               0 :                                 result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
     913               0 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
     914                 :                         }
     915               1 :                         return;
     916                 :                         break;
     917                 : 
     918                 :                 case IS_STRING: {
     919                 :                                 zval tmp;
     920                 : 
     921             116 :                                 if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
     922               4 :                                         goto convert_to_array;
     923                 :                                 }
     924             112 :                                 if (dim == NULL) {
     925               0 :                                         zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
     926                 :                                 }
     927                 : 
     928             112 :                                 if (Z_TYPE_P(dim) != IS_LONG) {
     929              15 :                                         switch(Z_TYPE_P(dim)) {
     930                 :                                                 /* case IS_LONG: */
     931                 :                                                 case IS_STRING:
     932                 :                                                 case IS_DOUBLE:
     933                 :                                                 case IS_NULL:
     934                 :                                                 case IS_BOOL:
     935                 :                                                         /* do nothing */
     936              15 :                                                         break;
     937                 :                                                 default:
     938               0 :                                                         zend_error(E_WARNING, "Illegal offset type");
     939                 :                                                         break;
     940                 :                                         }
     941                 : 
     942              15 :                                         tmp = *dim;
     943              15 :                                         zval_copy_ctor(&tmp);
     944              15 :                                         convert_to_long(&tmp);
     945              15 :                                         dim = &tmp;
     946                 :                                 }
     947             112 :                                 if (type != BP_VAR_UNSET) {
     948             111 :                                         SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
     949                 :                                 }
     950             112 :                                 container = *container_ptr;
     951             112 :                                 result->str_offset.str = container;
     952             112 :                                 PZVAL_LOCK(container);
     953             112 :                                 result->str_offset.offset = Z_LVAL_P(dim);
     954             112 :                                 result->var.ptr_ptr = NULL;
     955             112 :                                 result->var.ptr = NULL;
     956             112 :                                 return;
     957                 :                         }
     958                 :                         break;
     959                 : 
     960                 :                 case IS_OBJECT:
     961              45 :                         if (!Z_OBJ_HT_P(container)->read_dimension) {
     962               0 :                                 zend_error_noreturn(E_ERROR, "Cannot use object as array");
     963                 :                         } else {
     964                 :                                 zval *overloaded_result;
     965                 : 
     966              45 :                                 if (dim_is_tmp_var) {
     967               0 :                                         zval *orig = dim;
     968               0 :                                         MAKE_REAL_ZVAL_PTR(dim);
     969               0 :                                         ZVAL_NULL(orig);
     970                 :                                 }
     971              45 :                                 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
     972                 : 
     973              45 :                                 if (overloaded_result) {
     974              42 :                                         if (!Z_ISREF_P(overloaded_result)) {
     975              39 :                                                 if (Z_REFCOUNT_P(overloaded_result) > 0) {
     976               8 :                                                         zval *tmp = overloaded_result;
     977                 : 
     978               8 :                                                         ALLOC_ZVAL(overloaded_result);
     979               8 :                                                         *overloaded_result = *tmp;
     980               8 :                                                         zval_copy_ctor(overloaded_result);
     981               8 :                                                         Z_UNSET_ISREF_P(overloaded_result);
     982               8 :                                                         Z_SET_REFCOUNT_P(overloaded_result, 0);
     983                 :                                                 }
     984              39 :                                                 if (Z_TYPE_P(overloaded_result) != IS_OBJECT) {
     985               8 :                                                         zend_class_entry *ce = Z_OBJCE_P(container);
     986               8 :                                                         zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name);
     987                 :                                                 }
     988                 :                                         }
     989              42 :                                         retval = &overloaded_result;
     990                 :                                 } else {
     991               3 :                                         retval = &EG(error_zval_ptr);
     992                 :                                 }
     993              45 :                                 AI_SET_PTR(result->var, *retval);
     994              45 :                                 PZVAL_LOCK(*retval);
     995              45 :                                 if (dim_is_tmp_var) {
     996               0 :                                         zval_ptr_dtor(&dim);
     997                 :                                 }
     998                 :                         }
     999              45 :                         return;
    1000                 :                         break;
    1001                 : 
    1002                 :                 case IS_BOOL:
    1003               8 :                         if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
    1004               4 :                                 goto convert_to_array;
    1005                 :                         }
    1006                 :                         /* break missing intentionally */
    1007                 : 
    1008                 :                 default:
    1009              18 :                         if (type == BP_VAR_UNSET) {
    1010               0 :                                 zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
    1011               0 :                                 AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1012               0 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1013                 :                         } else {
    1014              18 :                                 zend_error(E_WARNING, "Cannot use a scalar value as an array");
    1015              18 :                                 result->var.ptr_ptr = &EG(error_zval_ptr);
    1016              18 :                                 PZVAL_LOCK(EG(error_zval_ptr));
    1017                 :                         }
    1018                 :                         break;
    1019                 :         }
    1020                 : }
    1021                 : 
    1022                 : static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
    1023         2959589 : {
    1024         2959589 :         zval *container = *container_ptr;
    1025                 :         zval **retval;
    1026                 : 
    1027         2959589 :         switch (Z_TYPE_P(container)) {
    1028                 : 
    1029                 :                 case IS_ARRAY:
    1030         2953151 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
    1031         2953151 :                         if (result) {
    1032         2953151 :                                 AI_SET_PTR(result->var, *retval);
    1033         2953151 :                                 PZVAL_LOCK(*retval);
    1034                 :                         }
    1035         2953151 :                         return;
    1036                 :                         break;
    1037                 : 
    1038                 :                 case IS_NULL:
    1039              58 :                         if (result) {
    1040              57 :                                 AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1041              57 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1042                 :                         }
    1043              58 :                         return;
    1044                 :                         break;
    1045                 : 
    1046                 :                 case IS_STRING: {
    1047                 :                                 zval tmp;
    1048                 : 
    1049            5570 :                                 if (Z_TYPE_P(dim) != IS_LONG) {
    1050              31 :                                         switch(Z_TYPE_P(dim)) {
    1051                 :                                                 /* case IS_LONG: */
    1052                 :                                                 case IS_STRING:
    1053                 :                                                 case IS_DOUBLE:
    1054                 :                                                 case IS_NULL:
    1055                 :                                                 case IS_BOOL:
    1056                 :                                                         /* do nothing */
    1057              28 :                                                         break;
    1058                 :                                                 default:
    1059               3 :                                                         zend_error(E_WARNING, "Illegal offset type");
    1060                 :                                                         break;
    1061                 :                                         }
    1062                 : 
    1063              31 :                                         tmp = *dim;
    1064              31 :                                         zval_copy_ctor(&tmp);
    1065              31 :                                         convert_to_long(&tmp);
    1066              31 :                                         dim = &tmp;
    1067                 :                                 }
    1068            5570 :                                 if (result) {
    1069            5563 :                                         if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) {
    1070              19 :                                                 zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
    1071                 :                                         }
    1072            5563 :                                         result->str_offset.str = container;
    1073            5563 :                                         PZVAL_LOCK(container);
    1074            5563 :                                         result->str_offset.offset = Z_LVAL_P(dim);
    1075            5563 :                                         result->var.ptr_ptr = NULL;
    1076            5563 :                                         result->var.ptr = NULL;
    1077                 :                                 }
    1078            5570 :                                 return;
    1079                 :                         }
    1080                 :                         break;
    1081                 : 
    1082                 :                 case IS_OBJECT:
    1083             710 :                         if (!Z_OBJ_HT_P(container)->read_dimension) {
    1084               0 :                                 zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1085                 :                         } else {
    1086                 :                                 zval *overloaded_result;
    1087                 : 
    1088             710 :                                 if (dim_is_tmp_var) {
    1089               6 :                                         zval *orig = dim;
    1090               6 :                                         MAKE_REAL_ZVAL_PTR(dim);
    1091               6 :                                         ZVAL_NULL(orig);
    1092                 :                                 }
    1093             710 :                                 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
    1094                 : 
    1095             707 :                                 if (overloaded_result) {
    1096             699 :                                         if (result) {
    1097             697 :                                                 AI_SET_PTR(result->var, overloaded_result);
    1098             697 :                                                 PZVAL_LOCK(overloaded_result);
    1099               2 :                                         } else if (Z_REFCOUNT_P(overloaded_result) == 0) {
    1100                 :                                                 /* Destroy unused result from offsetGet() magic method */
    1101               2 :                                                 Z_SET_REFCOUNT_P(overloaded_result, 1);
    1102               2 :                                                 zval_ptr_dtor(&overloaded_result);
    1103                 :                                         }
    1104               8 :                                 } else if (result) {
    1105               7 :                                         AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1106               7 :                                         PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1107                 :                                 }
    1108             707 :                                 if (dim_is_tmp_var) {
    1109               6 :                                         zval_ptr_dtor(&dim);
    1110                 :                                 }
    1111                 :                         }
    1112             707 :                         return;
    1113                 :                         break;
    1114                 : 
    1115                 :                 default:
    1116             100 :                         if (result) {
    1117             100 :                                 AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1118             100 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1119                 :                         }
    1120             100 :                         return;
    1121                 :                         break;
    1122                 :         }
    1123                 : }
    1124                 : 
    1125                 : static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC)
    1126             709 : {
    1127             709 :         zval *container = *container_ptr;;
    1128                 : 
    1129             709 :         if (Z_TYPE_P(container) != IS_OBJECT) {
    1130              39 :                 if (container == EG(error_zval_ptr)) {
    1131               1 :                         result->var.ptr_ptr = &EG(error_zval_ptr);
    1132               1 :                         PZVAL_LOCK(*result->var.ptr_ptr);
    1133               1 :                         return;
    1134                 :                 }
    1135                 : 
    1136                 :                 /* this should modify object only if it's empty */
    1137              72 :                 if (type != BP_VAR_UNSET &&
    1138                 :                     ((Z_TYPE_P(container) == IS_NULL ||
    1139                 :                      (Z_TYPE_P(container) == IS_BOOL && Z_LVAL_P(container)==0) ||
    1140                 :                      (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
    1141              34 :                         if (!PZVAL_IS_REF(container)) {
    1142              32 :                                 SEPARATE_ZVAL(container_ptr);
    1143              32 :                                 container = *container_ptr;
    1144                 :                         }
    1145              34 :                         object_init(container);
    1146                 :                 } else {
    1147               4 :                         zend_error(E_WARNING, "Attempt to modify property of non-object");
    1148               4 :                         result->var.ptr_ptr = &EG(error_zval_ptr);
    1149               4 :                         PZVAL_LOCK(EG(error_zval_ptr));
    1150               4 :                         return;
    1151                 :                 }
    1152                 :         }
    1153                 : 
    1154             704 :         if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
    1155             704 :                 zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC);
    1156             703 :                 if (NULL == ptr_ptr) {
    1157                 :                         zval *ptr;
    1158                 : 
    1159              54 :                         if (Z_OBJ_HT_P(container)->read_property &&
    1160                 :                                 (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC)) != NULL) {
    1161              54 :                                 AI_SET_PTR(result->var, ptr);
    1162              54 :                                 PZVAL_LOCK(ptr);
    1163                 :                         } else {
    1164               0 :                                 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
    1165                 :                         }
    1166                 :                 } else {
    1167             649 :                         result->var.ptr_ptr = ptr_ptr;
    1168             649 :                         PZVAL_LOCK(*ptr_ptr);
    1169                 :                 }
    1170               0 :         } else if (Z_OBJ_HT_P(container)->read_property) {
    1171               0 :                 zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC);
    1172                 : 
    1173               0 :                 AI_SET_PTR(result->var, ptr);
    1174               0 :                 PZVAL_LOCK(ptr);
    1175                 :         } else {
    1176               0 :                 zend_error(E_WARNING, "This object doesn't support property references");
    1177               0 :                 result->var.ptr_ptr = &EG(error_zval_ptr);
    1178               0 :                 PZVAL_LOCK(EG(error_zval_ptr));
    1179                 :         }
    1180                 : }
    1181                 : 
    1182                 : static inline zend_brk_cont_element* zend_brk_cont(const zval *nest_levels_zval, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)
    1183           55354 : {
    1184                 :         zval tmp;
    1185                 :         int nest_levels, original_nest_levels;
    1186                 :         zend_brk_cont_element *jmp_to;
    1187                 : 
    1188           55354 :         if (nest_levels_zval->type != IS_LONG) {
    1189               0 :                 tmp = *nest_levels_zval;
    1190               0 :                 zval_copy_ctor(&tmp);
    1191               0 :                 convert_to_long(&tmp);
    1192               0 :                 nest_levels = tmp.value.lval;
    1193                 :         } else {
    1194           55354 :                 nest_levels = nest_levels_zval->value.lval;
    1195                 :         }
    1196           55354 :         original_nest_levels = nest_levels;
    1197                 :         do {
    1198           55511 :                 if (array_offset==-1) {
    1199               0 :                         zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
    1200                 :                 }
    1201           55511 :                 jmp_to = &op_array->brk_cont_array[array_offset];
    1202           55511 :                 if (nest_levels>1) {
    1203             157 :                         zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
    1204                 : 
    1205             157 :                         switch (brk_opline->opcode) {
    1206                 :                                 case ZEND_SWITCH_FREE:
    1207               2 :                                         if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
    1208               0 :                                                 zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC);
    1209                 :                                         }
    1210               2 :                                         break;
    1211                 :                                 case ZEND_FREE:
    1212               0 :                                         if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
    1213               0 :                                                 zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var);
    1214                 :                                         }
    1215                 :                                         break;
    1216                 :                         }
    1217                 :                 }
    1218           55511 :                 array_offset = jmp_to->parent;
    1219           55511 :         } while (--nest_levels > 0);
    1220           55354 :         return jmp_to;
    1221                 : }
    1222                 : 
    1223                 : #if ZEND_INTENSIVE_DEBUGGING
    1224                 : 
    1225                 : #define CHECK_SYMBOL_TABLES()                                                                                                           \
    1226                 :         zend_hash_apply(&EG(symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);     \
    1227                 :         if (&EG(symbol_table)!=EG(active_symbol_table)) {                                                           \
    1228                 :                 zend_hash_apply(EG(active_symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);   \
    1229                 :         }
    1230                 : 
    1231                 : static int zend_check_symbol(zval **pz TSRMLS_DC)
    1232                 : {
    1233                 :         if (Z_TYPE_PP(pz) > 9) {
    1234                 :                 fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
    1235                 :         } else if (Z_TYPE_PP(pz) == IS_ARRAY) {
    1236                 :                 zend_hash_apply(Z_ARRVAL_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
    1237                 :         } else if (Z_TYPE_PP(pz) == IS_OBJECT) {
    1238                 : 
    1239                 :                 /* OBJ-TBI - doesn't support new object model! */
    1240                 :                 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
    1241                 :         }
    1242                 : 
    1243                 :         return 0;
    1244                 : }
    1245                 : 
    1246                 : 
    1247                 : #else
    1248                 : #define CHECK_SYMBOL_TABLES()
    1249                 : #endif
    1250                 : 
    1251                 : ZEND_API opcode_handler_t *zend_opcode_handlers;
    1252                 : 
    1253                 : ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
    1254               0 : {
    1255               0 :         zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr;
    1256               0 :         ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, execute_data_ptr->function_state.function->common.return_reference?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);
    1257               0 : }
    1258                 : 
    1259                 : #define ZEND_VM_NEXT_OPCODE() \
    1260                 :         CHECK_SYMBOL_TABLES() \
    1261                 :         EX(opline)++; \
    1262                 :         ZEND_VM_CONTINUE()
    1263                 : 
    1264                 : #define ZEND_VM_SET_OPCODE(new_op) \
    1265                 :         CHECK_SYMBOL_TABLES() \
    1266                 :         EX(opline) = new_op
    1267                 : 
    1268                 : #define ZEND_VM_JMP(new_op) \
    1269                 :         CHECK_SYMBOL_TABLES() \
    1270                 :         if (EXPECTED(!EG(exception))) { \
    1271                 :                 EX(opline) = new_op; \
    1272                 :         } \
    1273                 :         ZEND_VM_CONTINUE()
    1274                 : 
    1275                 : #define ZEND_VM_INC_OPCODE() \
    1276                 :         EX(opline)++
    1277                 : 
    1278                 : #include "zend_vm_execute.h"
    1279                 : 
    1280                 : ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
    1281               0 : {
    1282               0 :         if (opcode != ZEND_USER_OPCODE) {
    1283               0 :                 zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
    1284               0 :                 zend_user_opcode_handlers[opcode] = handler;
    1285               0 :                 return SUCCESS;
    1286                 :         }
    1287               0 :         return FAILURE;
    1288                 : }
    1289                 : 
    1290                 : ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
    1291               0 : {
    1292               0 :         return zend_user_opcode_handlers[opcode];
    1293                 : }
    1294                 : 
    1295               0 : ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
    1296               0 :         return get_zval_ptr(node, Ts, should_free, type);
    1297                 : }
    1298                 : 
    1299               0 : ZEND_API zval **zend_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
    1300               0 :         return get_zval_ptr_ptr(node, Ts, should_free, type);
    1301                 : }
    1302                 : 
    1303                 : /*
    1304                 :  * Local variables:
    1305                 :  * tab-width: 4
    1306                 :  * c-basic-offset: 4
    1307                 :  * indent-tabs-mode: t
    1308                 :  * End:
    1309                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:26:57 +0000 (3 days ago)

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