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

LCOV - code coverage report
Current view: top level - Zend - zend_execute.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 488 575 84.9 %
Date: 2014-07-23 Functions: 19 28 67.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2013 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$ */
      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             : {
      70    31619407 :         if (!Z_DELREF_P(z)) {
      71             :                 Z_SET_REFCOUNT_P(z, 1);
      72             :                 Z_UNSET_ISREF_P(z);
      73    17483417 :                 should_free->var = z;
      74             : /*              should_free->is_var = 1; */
      75             :         } else {
      76    14135990 :                 should_free->var = 0;
      77    28710774 :                 if (unref && Z_ISREF_P(z) && Z_REFCOUNT_P(z) == 1) {
      78             :                         Z_UNSET_ISREF_P(z);
      79             :                 }
      80             :                 GC_ZVAL_CHECK_POSSIBLE_ROOT(z);
      81             :         }
      82             : }
      83             : 
      84             : static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
      85             : {
      86       30837 :         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             : }
      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           0 : ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var)
     171             : {
     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             : {
     177    28733169 :         return should_free->var = &T(node->u.var).tmp_var;
     178             : }
     179             : 
     180       30822 : static zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
     181             : {
     182       30822 :         temp_variable *T = &T(node->u.var);
     183       30822 :         zval *str = T->str_offset.str;
     184             :         zval *ptr;
     185             : 
     186             :         /* string offset */
     187       30822 :         ALLOC_ZVAL(ptr);
     188       30822 :         T->str_offset.ptr = ptr;
     189       30822 :         should_free->var = ptr;
     190             : 
     191      123306 :         if (T->str_offset.str->type != IS_STRING
     192       61644 :                 || ((int)T->str_offset.offset < 0)
     193       30822 :                 || (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       30804 :                 ptr->value.str.val = estrndup(str->value.str.val + T->str_offset.offset, 1);
     198       30804 :                 ptr->value.str.len = 1;
     199             :         }
     200             :         PZVAL_UNLOCK_FREE(str);
     201             :         Z_SET_REFCOUNT_P(ptr, 1);
     202             :         Z_SET_ISREF_P(ptr);
     203       30822 :         ptr->type = IS_STRING;
     204       30822 :         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             : {
     209    25086279 :         zval *ptr = T(node->u.var).var.ptr;
     210    25086279 :         if (EXPECTED(ptr != NULL)) {
     211             :                 PZVAL_UNLOCK(ptr, should_free);
     212    25055457 :                 return ptr;
     213             :         } else {
     214       30822 :                 return _get_zval_ptr_var_string_offset(node, Ts, should_free TSRMLS_CC);
     215             :         }
     216             : }
     217             : 
     218     7929465 : static zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)
     219             : {
     220     7929465 :         zend_compiled_variable *cv = &CV_DEF_OF(var);
     221             : 
     222     8560118 :         if (!EG(active_symbol_table) ||
     223      630653 :             zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
     224     7916087 :                 switch (type) {
     225             :                         case BP_VAR_R:
     226             :                         case BP_VAR_UNSET:
     227         574 :                                 zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
     228             :                                 /* break missing intentionally */
     229             :                         case BP_VAR_IS:
     230         576 :                                 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             :                                 Z_ADDREF(EG(uninitialized_zval));
     237     7915511 :                                 if (!EG(active_symbol_table)) {
     238     7298785 :                                         *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
     239     7298785 :                                         **ptr = &EG(uninitialized_zval);
     240             :                                 } else {
     241      616726 :                                         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     7928889 :         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             : {
     251    49210282 :         zval ***ptr = &CV_OF(node->u.var);
     252             : 
     253    49210282 :         if (UNEXPECTED(*ptr == NULL)) {
     254       12978 :                 return *_get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);
     255             :         }
     256    49197304 :         return **ptr;
     257             : }
     258             : 
     259     3937207 : static inline zval *_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
     260             : {
     261             : /*      should_free->is_var = 0; */
     262     3937207 :         switch (node->op_type) {
     263             :                 case IS_CONST:
     264      485330 :                         should_free->var = 0;
     265      485330 :                         return &node->u.constant;
     266             :                         break;
     267             :                 case IS_TMP_VAR:
     268      237301 :                         should_free->var = TMP_FREE(&T(node->u.var).tmp_var);
     269      237301 :                         return &T(node->u.var).tmp_var;
     270             :                         break;
     271             :                 case IS_VAR:
     272      222887 :                         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     2991689 :                         should_free->var = 0;
     280     2991689 :                         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             : {
     289     6563863 :         zval** ptr_ptr = T(node->u.var).var.ptr_ptr;
     290             : 
     291     6563863 :         if (EXPECTED(ptr_ptr != NULL)) {
     292     6563697 :                 PZVAL_UNLOCK(*ptr_ptr, should_free);
     293             :         } else {
     294             :                 /* string offset */
     295         166 :                 PZVAL_UNLOCK(T(node->u.var).str_offset.str, should_free);
     296             :         }
     297     6563863 :         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             : {
     302    40945556 :         zval ***ptr = &CV_OF(node->u.var);
     303             : 
     304    40945556 :         if (UNEXPECTED(*ptr == NULL)) {
     305     7916487 :                 return _get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);
     306             :         }
     307    33029069 :         return *ptr;
     308             : }
     309             : 
     310     4969773 : static inline zval **_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
     311             : {
     312     4969773 :         if (node->op_type == IS_CV) {
     313     4969772 :                 should_free->var = 0;
     314     4969772 :                 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             : {
     325       31171 :         if (EXPECTED(EG(This) != NULL)) {
     326       31170 :                 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             : {
     335             :         if (op->op_type == IS_UNUSED) {
     336             :                 if (EXPECTED(EG(This) != NULL)) {
     337             :                         /* this should actually never be modified, _ptr_ptr is modified only when
     338             :                            the object is empty */
     339             :                         should_free->var = 0;
     340             :                         return &EG(This);
     341             :                 } else {
     342             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     343             :                 }
     344             :         }
     345             :         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             : {
     350      183900 :         if (EXPECTED(EG(This) != NULL)) {
     351      183898 :                 return &EG(This);
     352             :         } else {
     353           2 :                 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             : {
     360             :         if (op->op_type == IS_UNUSED) {
     361             :                 if (EXPECTED(EG(This) != NULL)) {
     362             :                         should_free->var = 0;
     363             :                         return EG(This);
     364             :                 } else {
     365             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     366             :                 }
     367             :         }
     368             :         return get_zval_ptr(op, Ts, should_free, type);
     369             : }
     370             : 
     371       68069 : static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC)
     372             : {
     373       68069 :         if (T->var.ptr) {
     374       68054 :                 if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */
     375       67790 :                         Z_DELREF_P(T->var.ptr);
     376             :                 }
     377       68054 :                 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       68069 : }
     385             : 
     386      859845 : static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)
     387             : {
     388      859845 :         zval *variable_ptr = *variable_ptr_ptr;
     389      859845 :         zval *value_ptr = *value_ptr_ptr;
     390             : 
     391      859856 :         if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {
     392          11 :                 variable_ptr_ptr = &EG(uninitialized_zval_ptr);
     393      859834 :         } else if (variable_ptr != value_ptr) {
     394      848880 :                 if (!PZVAL_IS_REF(value_ptr)) {
     395             :                         /* break it away */
     396             :                         Z_DELREF_P(value_ptr);
     397      572197 :                         if (Z_REFCOUNT_P(value_ptr)>0) {
     398          45 :                                 ALLOC_ZVAL(*value_ptr_ptr);
     399          45 :                                 **value_ptr_ptr = *value_ptr;
     400          45 :                                 value_ptr = *value_ptr_ptr;
     401          45 :                                 zendi_zval_copy_ctor(*value_ptr);
     402             :                         }
     403             :                         Z_SET_REFCOUNT_P(value_ptr, 1);
     404             :                         Z_SET_ISREF_P(value_ptr);
     405             :                 }
     406             : 
     407      848880 :                 *variable_ptr_ptr = value_ptr;
     408             :                 Z_ADDREF_P(value_ptr);
     409             : 
     410      848880 :                 zval_ptr_dtor(&variable_ptr);
     411       21908 :         } else if (!Z_ISREF_P(variable_ptr)) {
     412         847 :                 if (variable_ptr_ptr == value_ptr_ptr) {
     413        1366 :                         SEPARATE_ZVAL(variable_ptr_ptr);
     414         530 :                 } else if (variable_ptr==EG(uninitialized_zval_ptr)
     415         266 :                         || Z_REFCOUNT_P(variable_ptr)>2) {
     416             :                         /* we need to separate */
     417         524 :                         Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2);
     418         262 :                         ALLOC_ZVAL(*variable_ptr_ptr);
     419         262 :                         **variable_ptr_ptr = *variable_ptr;
     420         262 :                         zval_copy_ctor(*variable_ptr_ptr);
     421         262 :                         *value_ptr_ptr = *variable_ptr_ptr;
     422         262 :                         Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2);
     423             :                 }
     424         847 :                 Z_SET_ISREF_PP(variable_ptr_ptr);
     425             :         }
     426      859845 : }
     427             : 
     428             : /* this should modify object only if it's empty */
     429        4307 : static inline void make_real_object(zval **object_ptr TSRMLS_DC)
     430             : {
     431       17221 :         if (Z_TYPE_PP(object_ptr) == IS_NULL
     432        8612 :                 || (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0)
     433        4302 :                 || (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0)
     434             :         ) {
     435          47 :                 SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
     436          11 :                 zval_dtor(*object_ptr);
     437          11 :                 object_init(*object_ptr);
     438          11 :                 zend_error(E_STRICT, "Creating default object from empty value");
     439             :         }
     440        4307 : }
     441             : 
     442       88698 : 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)
     443             : {
     444       88698 :         *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);
     445             : 
     446       88698 :         *class_name = (*pce) ? (*pce)->name: cur_arg_info->class_name;
     447       88698 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     448         616 :                 return "implement interface ";
     449             :         } else {
     450       88082 :                 return "be an instance of ";
     451             :         }
     452             : }
     453             : 
     454          47 : 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)
     455             : {
     456          47 :         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
     457          47 :         char *fname = zf->common.function_name;
     458             :         char *fsep;
     459             :         char *fclass;
     460             : 
     461          47 :         if (zf->common.scope) {
     462          19 :                 fsep =  "::";
     463          19 :                 fclass = zf->common.scope->name;
     464             :         } else {
     465          28 :                 fsep =  "";
     466          28 :                 fclass = "";
     467             :         }
     468             : 
     469          50 :         if (ptr && ptr->op_array) {
     470          19 :                 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);
     471             :         } else {
     472          28 :                 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);
     473             :         }
     474          25 :         return 0;
     475             : }
     476             : 
     477    34554489 : static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC)
     478             : {
     479             :         zend_arg_info *cur_arg_info;
     480             :         char *need_msg;
     481             :         zend_class_entry *ce;
     482             : 
     483    69108978 :         if (!zf->common.arg_info
     484    34554489 :                 || arg_num>zf->common.num_args) {
     485      165733 :                 return 1;
     486             :         }
     487             : 
     488    34388756 :         cur_arg_info = &zf->common.arg_info[arg_num-1];
     489             : 
     490    34388756 :         if (cur_arg_info->class_name) {
     491             :                 const char *class_name;
     492             : 
     493       88734 :                 if (!arg) {
     494           2 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     495           2 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC);
     496             :                 }
     497       88732 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     498       88683 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     499       88683 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
     500          24 :                                 return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
     501             :                         }
     502          49 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
     503          13 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     504          13 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
     505             :                 }
     506    34300022 :         } else if (cur_arg_info->array_type_hint) {
     507         409 :                 if (!arg) {
     508           2 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC);
     509             :                 }
     510         407 :                 if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     511           6 :                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
     512             :                 }
     513             :         }
     514    34388709 :         return 1;
     515             : }
     516             : 
     517      103596 : 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)
     518             : 
     519             : {
     520      103596 :         zval *object = *object_ptr;
     521             :         zend_free_op free_value;
     522      103596 :         zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R);
     523      103596 :         zval **retval = &T(result->u.var).var.ptr;
     524             : 
     525      103596 :         if (Z_TYPE_P(object) != IS_OBJECT) {
     526          27 :                 if (object == EG(error_zval_ptr)) {
     527           0 :                         if (!RETURN_VALUE_UNUSED(result)) {
     528           0 :                                 *retval = EG(uninitialized_zval_ptr);
     529           0 :                                 PZVAL_LOCK(*retval);
     530             :                         }
     531           0 :                         FREE_OP(free_value);
     532           0 :                         return;
     533             :                 }
     534          65 :                 if (Z_TYPE_P(object) == IS_NULL ||
     535           9 :                     (Z_TYPE_P(object) == IS_BOOL && Z_LVAL_P(object) == 0) ||
     536           7 :                     (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
     537         105 :                         SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
     538          23 :                         object = *object_ptr;
     539          23 :                         Z_ADDREF_P(object);
     540          23 :                         zend_error(E_STRICT, "Creating default object from empty value");
     541          46 :                         if (Z_REFCOUNT_P(object) == 1) {
     542             :                                 /* object was removed by error handler, nothing to assign to */
     543           1 :                                 zval_ptr_dtor(&object);
     544           1 :                                 if (retval) {
     545           1 :                                         *retval = &EG(uninitialized_zval);
     546           1 :                                         PZVAL_LOCK(*retval);
     547             :                                 }
     548           1 :                                 FREE_OP(free_value);
     549           1 :                                 return;
     550             :                         }
     551          22 :                         Z_DELREF_P(object);
     552          22 :                         zval_dtor(object);
     553          22 :                         object_init(object);
     554             :                 } else {
     555           4 :                         zend_error(E_WARNING, "Attempt to assign property of non-object");
     556           4 :                         if (!RETURN_VALUE_UNUSED(result)) {
     557           0 :                                 *retval = EG(uninitialized_zval_ptr);
     558           0 :                                 PZVAL_LOCK(*retval);
     559             :                         }
     560           4 :                         FREE_OP(free_value);
     561           4 :                         return;
     562             :                 }
     563             :         }
     564             :         
     565             :         /* separate our value if necessary */
     566      103591 :         if (value_op->op_type == IS_TMP_VAR) {
     567         616 :                 zval *orig_value = value;
     568             : 
     569         616 :                 ALLOC_ZVAL(value);
     570         616 :                 *value = *orig_value;
     571         616 :                 Z_UNSET_ISREF_P(value);
     572         616 :                 Z_SET_REFCOUNT_P(value, 0);
     573      102975 :         } else if (value_op->op_type == IS_CONST) {
     574       89193 :                 zval *orig_value = value;
     575             : 
     576       89193 :                 ALLOC_ZVAL(value);
     577       89193 :                 *value = *orig_value;
     578       89193 :                 Z_UNSET_ISREF_P(value);
     579       89193 :                 Z_SET_REFCOUNT_P(value, 0);
     580       89193 :                 zval_copy_ctor(value);
     581             :         }
     582             : 
     583             : 
     584      103591 :         Z_ADDREF_P(value);
     585      103591 :         if (opcode == ZEND_ASSIGN_OBJ) {
     586      103053 :                 if (!Z_OBJ_HT_P(object)->write_property) {
     587           0 :                         zend_error(E_WARNING, "Attempt to assign property of non-object");
     588           0 :                         if (!RETURN_VALUE_UNUSED(result)) {
     589           0 :                                 *retval = EG(uninitialized_zval_ptr);
     590           0 :                                 PZVAL_LOCK(*retval);
     591             :                         }
     592           0 :                         if (value_op->op_type == IS_TMP_VAR) {
     593           0 :                                 FREE_ZVAL(value);
     594           0 :                         } else if (value_op->op_type == IS_CONST) {
     595           0 :                                 zval_ptr_dtor(&value);
     596             :                         }
     597           0 :                         FREE_OP(free_value);
     598           0 :                         return;
     599             :                 }
     600      103053 :                 Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);
     601             :         } else {
     602             :                 /* Note:  property_name in this case is really the array index! */
     603         538 :                 if (!Z_OBJ_HT_P(object)->write_dimension) {
     604           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
     605             :                 }
     606         538 :                 Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
     607             :         }
     608             : 
     609      103581 :         if (!RETURN_VALUE_UNUSED(result) && !EG(exception)) {
     610          29 :                 AI_SET_PTR(T(result->u.var).var, value);
     611          29 :                 PZVAL_LOCK(value);
     612             :         }
     613      103581 :         zval_ptr_dtor(&value);
     614      103581 :         FREE_OP_IF_VAR(free_value);
     615             : }
     616             : 
     617         145 : static inline int zend_assign_to_string_offset(const temp_variable *T, const zval *value, int value_type TSRMLS_DC)
     618             : {
     619         145 :         if (Z_TYPE_P(T->str_offset.str) == IS_STRING) {
     620             : 
     621         145 :                 if (((int)T->str_offset.offset < 0)) {
     622           1 :                         zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
     623           1 :                         return 0;
     624             :                 }
     625             : 
     626         144 :                 if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
     627           4 :                         Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
     628           4 :                         memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
     629             :                                ' ',
     630           4 :                                T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
     631           4 :                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
     632           4 :                         Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
     633             :                 }
     634             : 
     635         144 :                 if (Z_TYPE_P(value) != IS_STRING) {
     636          10 :                         zval tmp = *value;
     637             : 
     638          10 :                         if (value_type != IS_TMP_VAR) {
     639           8 :                                 zval_copy_ctor(&tmp);
     640             :                         }
     641          10 :                         convert_to_string(&tmp);
     642          10 :                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL(tmp)[0];
     643          10 :                         STR_FREE(Z_STRVAL(tmp));
     644             :                 } else {
     645         134 :                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(value)[0];
     646         134 :                         if (value_type == IS_TMP_VAR) {
     647             :                                 /* we can safely free final_value here
     648             :                                  * because separation is done only
     649             :                                  * in case value_type == IS_VAR */
     650          10 :                                 STR_FREE(Z_STRVAL_P(value));
     651             :                         }
     652             :                 }
     653             :                 /*
     654             :                  * the value of an assignment to a string offset is undefined
     655             :                 T(result->u.var).var = &T->str_offset.str;
     656             :                 */
     657             :         }
     658         144 :         return 1;
     659             : }
     660             : 
     661    17967353 : static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value, int is_tmp_var TSRMLS_DC)
     662             : {
     663    17967353 :         zval *variable_ptr = *variable_ptr_ptr;
     664             :         zval garbage;
     665             : 
     666    17967353 :         if (variable_ptr == EG(error_zval_ptr)) {
     667          15 :                 if (is_tmp_var) {
     668           0 :                         zval_dtor(value);
     669             :                 }
     670          15 :                 return EG(uninitialized_zval_ptr);
     671             :         }
     672             : 
     673    17967338 :         if (Z_TYPE_P(variable_ptr) == IS_OBJECT && Z_OBJ_HANDLER_P(variable_ptr, set)) {
     674           0 :                 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
     675           0 :                 return variable_ptr;
     676             :         }
     677             : 
     678    17967338 :         if (PZVAL_IS_REF(variable_ptr)) {
     679       30070 :                 if (variable_ptr!=value) {
     680       30069 :                         zend_uint refcount = Z_REFCOUNT_P(variable_ptr);
     681             : 
     682       30069 :                         garbage = *variable_ptr;
     683       30069 :                         *variable_ptr = *value;
     684             :                         Z_SET_REFCOUNT_P(variable_ptr, refcount);
     685             :                         Z_SET_ISREF_P(variable_ptr);
     686       30069 :                         if (!is_tmp_var) {
     687       27743 :                                 zendi_zval_copy_ctor(*variable_ptr);
     688             :                         }
     689       30069 :                         zendi_zval_dtor(garbage);
     690       30068 :                         return variable_ptr;
     691             :                 }
     692             :         } else {
     693    17937268 :                 if (Z_DELREF_P(variable_ptr)==0) {
     694    10031227 :                         if (!is_tmp_var) {
     695     8356087 :                                 if (variable_ptr==value) {
     696             :                                         Z_ADDREF_P(variable_ptr);
     697     8355923 :                                 } else if (PZVAL_IS_REF(value)) {
     698     1689424 :                                         garbage = *variable_ptr;
     699     1689424 :                                         *variable_ptr = *value;
     700     1689424 :                                         INIT_PZVAL(variable_ptr);
     701     1689424 :                                         zval_copy_ctor(variable_ptr);
     702     1689424 :                                         zendi_zval_dtor(garbage);
     703     1689421 :                                         return variable_ptr;
     704             :                                 } else {
     705             :                                         Z_ADDREF_P(value);
     706     6666499 :                                         *variable_ptr_ptr = value;
     707     6666499 :                                         if (variable_ptr != &EG(uninitialized_zval)) {
     708     6666499 :                                                 GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
     709     6666499 :                                                 zval_dtor(variable_ptr);
     710     6666499 :                                                 efree(variable_ptr);
     711             :                                         }
     712     6666499 :                                         return value;
     713             :                                 }
     714             :                         } else {
     715     1675140 :                                 garbage = *variable_ptr;
     716     1675140 :                                 *variable_ptr = *value;
     717     1675140 :                                 INIT_PZVAL(variable_ptr);
     718     1675140 :                                 zendi_zval_dtor(garbage);
     719     1675140 :                                 return variable_ptr;
     720             :                         }
     721             :                 } else { /* we need to split */
     722     7906041 :                         GC_ZVAL_CHECK_POSSIBLE_ROOT(*variable_ptr_ptr);
     723     7906041 :                         if (!is_tmp_var) {
     724     8553423 :                                 if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
     725      923724 :                                         ALLOC_ZVAL(variable_ptr);
     726      923724 :                                         *variable_ptr_ptr = variable_ptr;
     727      923724 :                                         *variable_ptr = *value;
     728             :                                         Z_SET_REFCOUNT_P(variable_ptr, 1);
     729      923724 :                                         zval_copy_ctor(variable_ptr);
     730             :                                 } else {
     731     5782251 :                                         *variable_ptr_ptr = value;
     732             :                                         Z_ADDREF_P(value);
     733             :                                 }
     734             :                         } else {
     735     1200066 :                                 ALLOC_ZVAL(*variable_ptr_ptr);
     736             :                                 Z_SET_REFCOUNT_P(value, 1);
     737     1200066 :                                 **variable_ptr_ptr = *value;
     738             :                         }
     739             :                 }
     740     7906205 :                 Z_UNSET_ISREF_PP(variable_ptr_ptr);
     741             :         }
     742             : 
     743     7906206 :         return *variable_ptr_ptr;
     744             : }
     745             : 
     746             : 
     747             : /* Utility Functions for Extensions */
     748           0 : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     749             : {
     750           0 :         if (extension->statement_handler) {
     751           0 :                 extension->statement_handler(op_array);
     752             :         }
     753           0 : }
     754             : 
     755             : 
     756           0 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     757             : {
     758           0 :         if (extension->fcall_begin_handler) {
     759           0 :                 extension->fcall_begin_handler(op_array);
     760             :         }
     761           0 : }
     762             : 
     763             : 
     764           0 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     765             : {
     766           0 :         if (extension->fcall_end_handler) {
     767           0 :                 extension->fcall_end_handler(op_array);
     768             :         }
     769           0 : }
     770             : 
     771             : 
     772     1762557 : static inline HashTable *zend_get_target_symbol_table(const zend_op *opline, const temp_variable *Ts, int type, const zval *variable TSRMLS_DC)
     773             : {
     774     1762557 :         switch (opline->op2.u.EA.type) {
     775             :                 case ZEND_FETCH_LOCAL:
     776     1030417 :                         if (!EG(active_symbol_table)) {
     777       32620 :                                 zend_rebuild_symbol_table(TSRMLS_C);
     778             :                         }
     779     1030417 :                         return EG(active_symbol_table);
     780             :                         break;
     781             :                 case ZEND_FETCH_GLOBAL:
     782             :                 case ZEND_FETCH_GLOBAL_LOCK:
     783      730644 :                         return &EG(symbol_table);
     784             :                         break;
     785             :                 case ZEND_FETCH_STATIC:
     786        1496 :                         if (!EG(active_op_array)->static_variables) {
     787           0 :                                 ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
     788           0 :                                 zend_hash_init(EG(active_op_array)->static_variables, 2, NULL, ZVAL_PTR_DTOR, 0);
     789             :                         }
     790        1496 :                         return EG(active_op_array)->static_variables;
     791             :                         break;
     792             :                 EMPTY_SWITCH_DEFAULT_CASE()
     793             :         }
     794           0 :         return NULL;
     795             : }
     796             : 
     797     8266306 : static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int type TSRMLS_DC)
     798             : {
     799             :         zval **retval;
     800             :         char *offset_key;
     801             :         int offset_key_length;
     802             :         long index;
     803             : 
     804     8266306 :         switch (dim->type) {
     805             :                 case IS_NULL:
     806          10 :                         offset_key = "";
     807          10 :                         offset_key_length = 0;
     808          10 :                         goto fetch_string_dim;
     809             : 
     810             :                 case IS_STRING:
     811             :                         
     812     3658473 :                         offset_key = dim->value.str.val;
     813     3658473 :                         offset_key_length = dim->value.str.len;
     814             :                         
     815             : fetch_string_dim:
     816     3658483 :                         if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {
     817     1712833 :                                 switch (type) {
     818             :                                         case BP_VAR_R:
     819      108311 :                                                 zend_error(E_NOTICE, "Undefined index: %s", offset_key);
     820             :                                                 /* break missing intentionally */
     821             :                                         case BP_VAR_UNSET:
     822             :                                         case BP_VAR_IS:
     823      108311 :                                                 retval = &EG(uninitialized_zval_ptr);
     824      108311 :                                                 break;
     825             :                                         case BP_VAR_RW:
     826           1 :                                                 zend_error(E_NOTICE,"Undefined index: %s", offset_key);
     827             :                                                 /* break missing intentionally */
     828             :                                         case BP_VAR_W: {
     829     1604522 :                                                         zval *new_zval = &EG(uninitialized_zval);
     830             : 
     831     1604522 :                                                         Z_ADDREF_P(new_zval);
     832     1604522 :                                                         zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval);
     833             :                                                 }
     834             :                                                 break;
     835             :                                 }
     836             :                         }
     837     3658483 :                         break;
     838             :                 case IS_DOUBLE:
     839         108 :                         index = zend_dval_to_lval(Z_DVAL_P(dim));
     840          54 :                         goto num_index;
     841             :                 case IS_RESOURCE:
     842           3 :                         zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
     843             :                         /* Fall Through */
     844             :                 case IS_BOOL:
     845             :                 case IS_LONG:
     846     4607763 :                         index = Z_LVAL_P(dim);
     847             : num_index:
     848     4607817 :                         if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) {
     849      394471 :                                 switch (type) {
     850             :                                         case BP_VAR_R:
     851          12 :                                                 zend_error(E_NOTICE,"Undefined offset: %ld", index);
     852             :                                                 /* break missing intentionally */
     853             :                                         case BP_VAR_UNSET:
     854             :                                         case BP_VAR_IS:
     855          13 :                                                 retval = &EG(uninitialized_zval_ptr);
     856          13 :                                                 break;
     857             :                                         case BP_VAR_RW:
     858           0 :                                                 zend_error(E_NOTICE,"Undefined offset: %ld", index);
     859             :                                                 /* break missing intentionally */
     860             :                                         case BP_VAR_W: {
     861      394458 :                                                 zval *new_zval = &EG(uninitialized_zval);
     862             : 
     863      394458 :                                                 Z_ADDREF_P(new_zval);
     864      394458 :                                                 zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval);
     865             :                                         }
     866             :                                         break;
     867             :                                 }
     868             :                         }
     869     4607817 :                         break;
     870             : 
     871             :                 default:
     872           6 :                         zend_error(E_WARNING, "Illegal offset type");
     873           6 :                         return (type == BP_VAR_W || type == BP_VAR_RW) ?
     874             :                                 &EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
     875             :         }
     876     8266300 :         return retval;
     877             : }
     878             : 
     879     4336297 : static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
     880             : {
     881     4336297 :         zval *container = *container_ptr;
     882             :         zval **retval;
     883             : 
     884     4336297 :         switch (Z_TYPE_P(container)) {
     885             : 
     886             :                 case IS_ARRAY:
     887     9215839 :                         if (type != BP_VAR_UNSET && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) {
     888      399064 :                                 SEPARATE_ZVAL(container_ptr);
     889       99766 :                                 container = *container_ptr;
     890             :                         }
     891             : fetch_from_array:
     892     4336077 :                         if (dim == NULL) {
     893      663305 :                                 zval *new_zval = &EG(uninitialized_zval);
     894             : 
     895      663305 :                                 Z_ADDREF_P(new_zval);
     896      663305 :                                 if (zend_hash_next_index_insert(Z_ARRVAL_P(container), &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) {
     897           1 :                                         zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
     898           1 :                                         retval = &EG(error_zval_ptr);
     899           1 :                                         Z_DELREF_P(new_zval);
     900             :                                 }
     901             :                         } else {
     902     3672772 :                                 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
     903             :                         }
     904     4336077 :                         result->var.ptr_ptr = retval;
     905     4336077 :                         PZVAL_LOCK(*retval);
     906     4336077 :                         return;
     907             :                         break;
     908             : 
     909             :                 case IS_NULL:
     910        1223 :                         if (container == EG(error_zval_ptr)) {
     911           1 :                                 result->var.ptr_ptr = &EG(error_zval_ptr);
     912           1 :                                 PZVAL_LOCK(EG(error_zval_ptr));
     913        1222 :                         } else if (type != BP_VAR_UNSET) {
     914             : convert_to_array:
     915        1233 :                                 if (!PZVAL_IS_REF(container)) {
     916        4868 :                                         SEPARATE_ZVAL(container_ptr);
     917        1232 :                                         container = *container_ptr;
     918             :                                 }
     919        1233 :                                 zval_dtor(container);
     920        1233 :                                 array_init(container);
     921        1233 :                                 goto fetch_from_array;
     922             :                         } else {
     923             :                                 /* for read-mode only */
     924           0 :                                 result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
     925           0 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
     926             :                         }
     927           1 :                         return;
     928             :                         break;
     929             : 
     930             :                 case IS_STRING: {
     931             :                                 zval tmp;
     932             : 
     933         155 :                                 if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
     934           4 :                                         goto convert_to_array;
     935             :                                 }
     936         151 :                                 if (dim == NULL) {
     937           0 :                                         zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
     938             :                                 }
     939             : 
     940         151 :                                 if (type != BP_VAR_UNSET) {
     941         466 :                                         SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
     942             :                                 }
     943             : 
     944         151 :                                 if (Z_TYPE_P(dim) != IS_LONG) {
     945          16 :                                         switch(Z_TYPE_P(dim)) {
     946             :                                                 /* case IS_LONG: */
     947             :                                                 case IS_STRING:
     948             :                                                 case IS_DOUBLE:
     949             :                                                 case IS_NULL:
     950             :                                                 case IS_BOOL:
     951             :                                                         /* do nothing */
     952          15 :                                                         break;
     953             :                                                 default:
     954           1 :                                                         zend_error(E_WARNING, "Illegal offset type");
     955             :                                                         break;
     956             :                                         }
     957             : 
     958          16 :                                         tmp = *dim;
     959          16 :                                         zval_copy_ctor(&tmp);
     960          16 :                                         convert_to_long(&tmp);
     961          16 :                                         dim = &tmp;
     962             :                                 }
     963         151 :                                 container = *container_ptr;
     964         151 :                                 result->str_offset.str = container;
     965             :                                 PZVAL_LOCK(container);
     966         151 :                                 result->str_offset.offset = Z_LVAL_P(dim);
     967         151 :                                 result->var.ptr_ptr = NULL;
     968         151 :                                 result->var.ptr = NULL;
     969         151 :                                 return;
     970             :                         }
     971             :                         break;
     972             : 
     973             :                 case IS_OBJECT:
     974          49 :                         if (!Z_OBJ_HT_P(container)->read_dimension) {
     975           0 :                                 zend_error_noreturn(E_ERROR, "Cannot use object as array");
     976             :                         } else {
     977             :                                 zval *overloaded_result;
     978             : 
     979          49 :                                 if (dim_is_tmp_var) {
     980           0 :                                         zval *orig = dim;
     981           0 :                                         MAKE_REAL_ZVAL_PTR(dim);
     982           0 :                                         ZVAL_NULL(orig);
     983             :                                 }
     984          49 :                                 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
     985             : 
     986          49 :                                 if (overloaded_result) {
     987          92 :                                         if (!Z_ISREF_P(overloaded_result)) {
     988          80 :                                                 if (Z_REFCOUNT_P(overloaded_result) > 0) {
     989           9 :                                                         zval *tmp = overloaded_result;
     990             : 
     991           9 :                                                         ALLOC_ZVAL(overloaded_result);
     992           9 :                                                         *overloaded_result = *tmp;
     993           9 :                                                         zval_copy_ctor(overloaded_result);
     994           9 :                                                         Z_UNSET_ISREF_P(overloaded_result);
     995           9 :                                                         Z_SET_REFCOUNT_P(overloaded_result, 0);
     996             :                                                 }
     997          40 :                                                 if (Z_TYPE_P(overloaded_result) != IS_OBJECT) {
     998           9 :                                                         zend_class_entry *ce = Z_OBJCE_P(container);
     999           9 :                                                         zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name);
    1000             :                                                 }
    1001             :                                         }
    1002          46 :                                         retval = &overloaded_result;
    1003             :                                 } else {
    1004           3 :                                         retval = &EG(error_zval_ptr);
    1005             :                                 }
    1006          49 :                                 AI_SET_PTR(result->var, *retval);
    1007          49 :                                 PZVAL_LOCK(*retval);
    1008          49 :                                 if (dim_is_tmp_var) {
    1009           0 :                                         zval_ptr_dtor(&dim);
    1010             :                                 }
    1011             :                         }
    1012          49 :                         return;
    1013             :                         break;
    1014             : 
    1015             :                 case IS_BOOL:
    1016          11 :                         if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
    1017           7 :                                 goto convert_to_array;
    1018             :                         }
    1019             :                         /* break missing intentionally */
    1020             : 
    1021             :                 default:
    1022          19 :                         if (type == BP_VAR_UNSET) {
    1023           0 :                                 zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
    1024           0 :                                 AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1025           0 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1026             :                         } else {
    1027          19 :                                 zend_error(E_WARNING, "Cannot use a scalar value as an array");
    1028          19 :                                 result->var.ptr_ptr = &EG(error_zval_ptr);
    1029          19 :                                 PZVAL_LOCK(EG(error_zval_ptr));
    1030             :                         }
    1031             :                         break;
    1032             :         }
    1033             : }
    1034             : 
    1035     4625255 : static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
    1036             : {
    1037     4625255 :         zval *container = *container_ptr;
    1038             :         zval **retval;
    1039             : 
    1040     4625255 :         switch (Z_TYPE_P(container)) {
    1041             : 
    1042             :                 case IS_ARRAY:
    1043     4593513 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
    1044     4593513 :                         if (result) {
    1045     4593513 :                                 AI_SET_PTR(result->var, *retval);
    1046     4593513 :                                 PZVAL_LOCK(*retval);
    1047             :                         }
    1048     4593513 :                         return;
    1049             :                         break;
    1050             : 
    1051             :                 case IS_NULL:
    1052          64 :                         if (result) {
    1053          62 :                                 AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1054          62 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1055             :                         }
    1056          64 :                         return;
    1057             :                         break;
    1058             : 
    1059             :                 case IS_STRING: {
    1060             :                                 zval tmp;
    1061             : 
    1062       30845 :                                 if (Z_TYPE_P(dim) != IS_LONG) {
    1063          39 :                                         switch(Z_TYPE_P(dim)) {
    1064             :                                                 /* case IS_LONG: */
    1065             :                                                 case IS_STRING:
    1066             :                                                 case IS_DOUBLE:
    1067             :                                                 case IS_NULL:
    1068             :                                                 case IS_BOOL:
    1069             :                                                         /* do nothing */
    1070          36 :                                                         break;
    1071             :                                                 default:
    1072           3 :                                                         zend_error(E_WARNING, "Illegal offset type");
    1073             :                                                         break;
    1074             :                                         }
    1075             : 
    1076          39 :                                         tmp = *dim;
    1077          39 :                                         zval_copy_ctor(&tmp);
    1078          39 :                                         convert_to_long(&tmp);
    1079          39 :                                         dim = &tmp;
    1080             :                                 }
    1081       30845 :                                 if (result) {
    1082       30838 :                                         if ((Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) && type != BP_VAR_IS) {
    1083          19 :                                                 zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
    1084             :                                         }
    1085       30838 :                                         result->str_offset.str = container;
    1086             :                                         PZVAL_LOCK(container);
    1087       30838 :                                         result->str_offset.offset = Z_LVAL_P(dim);
    1088       30838 :                                         result->var.ptr_ptr = NULL;
    1089       30838 :                                         result->var.ptr = NULL;
    1090             :                                 }
    1091       30845 :                                 return;
    1092             :                         }
    1093             :                         break;
    1094             : 
    1095             :                 case IS_OBJECT:
    1096         732 :                         if (!Z_OBJ_HT_P(container)->read_dimension) {
    1097           0 :                                 zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1098             :                         } else {
    1099             :                                 zval *overloaded_result;
    1100             : 
    1101         732 :                                 if (dim_is_tmp_var) {
    1102           6 :                                         zval *orig = dim;
    1103          12 :                                         MAKE_REAL_ZVAL_PTR(dim);
    1104           6 :                                         ZVAL_NULL(orig);
    1105             :                                 }
    1106         732 :                                 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
    1107             : 
    1108         728 :                                 if (overloaded_result) {
    1109         720 :                                         if (result) {
    1110         718 :                                                 AI_SET_PTR(result->var, overloaded_result);
    1111         718 :                                                 PZVAL_LOCK(overloaded_result);
    1112           4 :                                         } else if (Z_REFCOUNT_P(overloaded_result) == 0) {
    1113             :                                                 /* Destroy unused result from offsetGet() magic method */
    1114           2 :                                                 Z_SET_REFCOUNT_P(overloaded_result, 1);
    1115           2 :                                                 zval_ptr_dtor(&overloaded_result);
    1116             :                                         }
    1117           8 :                                 } else if (result) {
    1118           7 :                                         AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1119           7 :                                         PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1120             :                                 }
    1121         728 :                                 if (dim_is_tmp_var) {
    1122           6 :                                         zval_ptr_dtor(&dim);
    1123             :                                 }
    1124             :                         }
    1125         728 :                         return;
    1126             :                         break;
    1127             : 
    1128             :                 default:
    1129         101 :                         if (result) {
    1130         101 :                                 AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
    1131         101 :                                 PZVAL_LOCK(EG(uninitialized_zval_ptr));
    1132             :                         }
    1133         101 :                         return;
    1134             :                         break;
    1135             :         }
    1136             : }
    1137             : 
    1138      175444 : static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC)
    1139             : {
    1140      175444 :         zval *container = *container_ptr;;
    1141             : 
    1142      175444 :         if (Z_TYPE_P(container) != IS_OBJECT) {
    1143          44 :                 if (container == EG(error_zval_ptr)) {
    1144           1 :                         result->var.ptr_ptr = &EG(error_zval_ptr);
    1145           1 :                         PZVAL_LOCK(*result->var.ptr_ptr);
    1146           1 :                         return;
    1147             :                 }
    1148             : 
    1149             :                 /* this should modify object only if it's empty */
    1150         141 :                 if (type != BP_VAR_UNSET &&
    1151          43 :                     ((Z_TYPE_P(container) == IS_NULL ||
    1152           9 :                      (Z_TYPE_P(container) == IS_BOOL && Z_LVAL_P(container)==0) ||
    1153           9 :                      (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
    1154          37 :                         if (!PZVAL_IS_REF(container)) {
    1155         134 :                                 SEPARATE_ZVAL(container_ptr);
    1156          35 :                                 container = *container_ptr;
    1157             :                         }
    1158          37 :                         object_init(container);
    1159             :                 } else {
    1160           6 :                         zend_error(E_WARNING, "Attempt to modify property of non-object");
    1161           6 :                         result->var.ptr_ptr = &EG(error_zval_ptr);
    1162           6 :                         PZVAL_LOCK(EG(error_zval_ptr));
    1163           6 :                         return;
    1164             :                 }
    1165             :         }
    1166             : 
    1167      175437 :         if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
    1168      175437 :                 zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC);
    1169      175436 :                 if (NULL == ptr_ptr) {
    1170             :                         zval *ptr;
    1171             : 
    1172         162 :                         if (Z_OBJ_HT_P(container)->read_property &&
    1173          54 :                                 (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC)) != NULL) {
    1174          54 :                                 AI_SET_PTR(result->var, ptr);
    1175             :                                 PZVAL_LOCK(ptr);
    1176             :                         } else {
    1177           0 :                                 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
    1178             :                         }
    1179             :                 } else {
    1180      175382 :                         result->var.ptr_ptr = ptr_ptr;
    1181      175382 :                         PZVAL_LOCK(*ptr_ptr);
    1182             :                 }
    1183           0 :         } else if (Z_OBJ_HT_P(container)->read_property) {
    1184           0 :                 zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC);
    1185             : 
    1186           0 :                 AI_SET_PTR(result->var, ptr);
    1187             :                 PZVAL_LOCK(ptr);
    1188             :         } else {
    1189           0 :                 zend_error(E_WARNING, "This object doesn't support property references");
    1190           0 :                 result->var.ptr_ptr = &EG(error_zval_ptr);
    1191           0 :                 PZVAL_LOCK(EG(error_zval_ptr));
    1192             :         }
    1193             : }
    1194             : 
    1195       70442 : 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)
    1196             : {
    1197             :         zval tmp;
    1198             :         int nest_levels, original_nest_levels;
    1199             :         zend_brk_cont_element *jmp_to;
    1200             : 
    1201       70442 :         if (nest_levels_zval->type != IS_LONG) {
    1202           0 :                 tmp = *nest_levels_zval;
    1203           0 :                 zval_copy_ctor(&tmp);
    1204           0 :                 convert_to_long(&tmp);
    1205           0 :                 nest_levels = tmp.value.lval;
    1206             :         } else {
    1207       70442 :                 nest_levels = nest_levels_zval->value.lval;
    1208             :         }
    1209       70442 :         original_nest_levels = nest_levels;
    1210             :         do {
    1211       70599 :                 if (array_offset==-1) {
    1212           0 :                         zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
    1213             :                 }
    1214       70599 :                 jmp_to = &op_array->brk_cont_array[array_offset];
    1215       70599 :                 if (nest_levels>1) {
    1216         157 :                         zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
    1217             : 
    1218         157 :                         switch (brk_opline->opcode) {
    1219             :                                 case ZEND_SWITCH_FREE:
    1220           2 :                                         if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
    1221           0 :                                                 zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC);
    1222             :                                         }
    1223           2 :                                         break;
    1224             :                                 case ZEND_FREE:
    1225           0 :                                         if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {
    1226           0 :                                                 zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var);
    1227             :                                         }
    1228             :                                         break;
    1229             :                         }
    1230             :                 }
    1231       70599 :                 array_offset = jmp_to->parent;
    1232       70599 :         } while (--nest_levels > 0);
    1233       70442 :         return jmp_to;
    1234             : }
    1235             : 
    1236             : #if ZEND_INTENSIVE_DEBUGGING
    1237             : 
    1238             : #define CHECK_SYMBOL_TABLES()                                                                                                           \
    1239             :         zend_hash_apply(&EG(symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);     \
    1240             :         if (&EG(symbol_table)!=EG(active_symbol_table)) {                                                           \
    1241             :                 zend_hash_apply(EG(active_symbol_table), (apply_func_t) zend_check_symbol TSRMLS_CC);   \
    1242             :         }
    1243             : 
    1244             : static int zend_check_symbol(zval **pz TSRMLS_DC)
    1245             : {
    1246             :         if (Z_TYPE_PP(pz) > 9) {
    1247             :                 fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
    1248             : /* See http://support.microsoft.com/kb/190351 */
    1249             : #ifdef PHP_WIN32
    1250             :                 fflush(stderr);
    1251             : #endif
    1252             :         } else if (Z_TYPE_PP(pz) == IS_ARRAY) {
    1253             :                 zend_hash_apply(Z_ARRVAL_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
    1254             :         } else if (Z_TYPE_PP(pz) == IS_OBJECT) {
    1255             : 
    1256             :                 /* OBJ-TBI - doesn't support new object model! */
    1257             :                 zend_hash_apply(Z_OBJPROP_PP(pz), (apply_func_t) zend_check_symbol TSRMLS_CC);
    1258             :         }
    1259             : 
    1260             :         return 0;
    1261             : }
    1262             : 
    1263             : 
    1264             : #else
    1265             : #define CHECK_SYMBOL_TABLES()
    1266             : #endif
    1267             : 
    1268             : ZEND_API opcode_handler_t *zend_opcode_handlers;
    1269             : 
    1270           0 : ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
    1271             : {
    1272           0 :         zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr;
    1273           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);
    1274           0 : }
    1275             : 
    1276             : #define ZEND_VM_NEXT_OPCODE() \
    1277             :         CHECK_SYMBOL_TABLES() \
    1278             :         EX(opline)++; \
    1279             :         ZEND_VM_CONTINUE()
    1280             : 
    1281             : #define ZEND_VM_SET_OPCODE(new_op) \
    1282             :         CHECK_SYMBOL_TABLES() \
    1283             :         EX(opline) = new_op
    1284             : 
    1285             : #define ZEND_VM_JMP(new_op) \
    1286             :         CHECK_SYMBOL_TABLES() \
    1287             :         if (EXPECTED(!EG(exception))) { \
    1288             :                 EX(opline) = new_op; \
    1289             :         } \
    1290             :         ZEND_VM_CONTINUE()
    1291             : 
    1292             : #define ZEND_VM_INC_OPCODE() \
    1293             :         EX(opline)++
    1294             : 
    1295             : #include "zend_vm_execute.h"
    1296             : 
    1297           0 : ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
    1298             : {
    1299           0 :         if (opcode != ZEND_USER_OPCODE) {
    1300           0 :                 zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
    1301           0 :                 zend_user_opcode_handlers[opcode] = handler;
    1302           0 :                 return SUCCESS;
    1303             :         }
    1304           0 :         return FAILURE;
    1305             : }
    1306             : 
    1307           0 : ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
    1308             : {
    1309           0 :         return zend_user_opcode_handlers[opcode];
    1310             : }
    1311             : 
    1312           0 : ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
    1313           0 :         return get_zval_ptr(node, Ts, should_free, type);
    1314             : }
    1315             : 
    1316           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) {
    1317           0 :         return get_zval_ptr_ptr(node, Ts, should_free, type);
    1318             : }
    1319             : 
    1320             : /*
    1321             :  * Local variables:
    1322             :  * tab-width: 4
    1323             :  * c-basic-offset: 4
    1324             :  * indent-tabs-mode: t
    1325             :  * End:
    1326             :  */

Generated by: LCOV version 1.10

Generated at Wed, 23 Jul 2014 19:58:29 +0000 (2 days ago)

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