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: 609 700 87.0 %
Date: 2014-09-27 Functions: 28 36 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2014 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_generators.h"
      39             : #include "zend_vm.h"
      40             : #include "zend_dtrace.h"
      41             : #include "zend_inheritance.h"
      42             : 
      43             : /* Virtual current working directory support */
      44             : #include "zend_virtual_cwd.h"
      45             : 
      46             : #define _CONST_CODE  0
      47             : #define _TMP_CODE    1
      48             : #define _VAR_CODE    2
      49             : #define _UNUSED_CODE 3
      50             : #define _CV_CODE     4
      51             : 
      52             : typedef int (*incdec_t)(zval *);
      53             : 
      54             : #define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
      55             : #define get_zval_ptr_deref(op_type, node, ex, should_free, type) _get_zval_ptr_deref(op_type, node, ex, should_free, type TSRMLS_CC)
      56             : #define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
      57             : #define get_zval_ptr_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
      58             : #define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
      59             : #define get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
      60             : 
      61             : /* Prototypes */
      62             : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
      63             : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
      64             : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
      65             : 
      66             : #define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
      67             : 
      68          70 : static ZEND_FUNCTION(pass)
      69             : {
      70          70 : }
      71             : 
      72             : static const zend_internal_function zend_pass_function = {
      73             :         ZEND_INTERNAL_FUNCTION, /* type              */
      74             :         0,                      /* fn_flags          */
      75             :         NULL,                   /* name              */
      76             :         NULL,                   /* scope             */
      77             :         NULL,                   /* prototype         */
      78             :         0,                      /* num_args          */
      79             :         0,                      /* required_num_args */
      80             :         NULL,                   /* arg_info          */
      81             :         ZEND_FN(pass),          /* handler           */
      82             :         NULL                    /* module            */
      83             : };
      84             : 
      85             : #undef zval_ptr_dtor
      86             : #define zval_ptr_dtor(zv) i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC TSRMLS_CC)
      87             : 
      88             : #define PZVAL_LOCK(z) if (Z_REFCOUNTED_P(z)) Z_ADDREF_P((z))
      89             : #define SELECTIVE_PZVAL_LOCK(pzv, opline)       if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
      90             : 
      91             : #define READY_TO_DESTROY(zv) \
      92             :         (zv && Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) == 1)
      93             : 
      94             : #define EXTRACT_ZVAL_PTR(zv) do {                                               \
      95             :                 zval *__zv = (zv);                                                              \
      96             :                 if (Z_TYPE_P(__zv) == IS_INDIRECT) {                    \
      97             :                         ZVAL_COPY(__zv, Z_INDIRECT_P(__zv));            \
      98             :                 }                                                                                               \
      99             :         } while (0)
     100             : 
     101             : #define FREE_OP(should_free) \
     102             :         if (should_free.var) { \
     103             :                 zval_ptr_dtor_nogc(should_free.var); \
     104             :         }
     105             : 
     106             : #define FREE_OP_VAR_PTR(should_free) \
     107             :         if (should_free.var) { \
     108             :                 zval_ptr_dtor_nogc(should_free.var); \
     109             :         }
     110             : 
     111             : /* End of zend_execute_locks.h */
     112             : 
     113             : #define CV_DEF_OF(i) (EX(func)->op_array.vars[i])
     114             : 
     115             : #define CTOR_CALL_BIT    0x1
     116             : #define CTOR_USED_BIT    0x2
     117             : 
     118             : #define IS_CTOR_CALL(ce) (((zend_uintptr_t)(ce)) & CTOR_CALL_BIT)
     119             : #define IS_CTOR_USED(ce) (((zend_uintptr_t)(ce)) & CTOR_USED_BIT)
     120             : 
     121             : #define ENCODE_CTOR(ce, used) \
     122             :         ((zend_class_entry*)(((zend_uintptr_t)(ce)) | CTOR_CALL_BIT | ((used) ? CTOR_USED_BIT : 0)))
     123             : #define DECODE_CTOR(ce) \
     124             :         ((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT)))
     125             : 
     126             : #undef EX
     127             : #define EX(element) execute_data->element
     128             : 
     129           0 : ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data, uint32_t var)
     130             : {
     131           0 :         return EX_VAR(var);
     132             : }
     133             : 
     134             : static zend_always_inline zval *_get_zval_ptr_tmp(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
     135             : {
     136    32660011 :         zval *ret = EX_VAR(var);
     137    32660011 :         should_free->var = ret;
     138             : 
     139             :         ZEND_ASSERT(Z_TYPE_P(ret) != IS_REFERENCE);
     140             : 
     141    32660011 :         return ret;
     142             : }
     143             : 
     144             : static zend_always_inline zval *_get_zval_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
     145             : {
     146     9772976 :         zval *ret = EX_VAR(var);
     147             : 
     148     9772976 :         should_free->var = ret;
     149     9772976 :         return ret;
     150             : }
     151             : 
     152             : static zend_always_inline zval *_get_zval_ptr_var_deref(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
     153             : {
     154    15030556 :         zval *ret = EX_VAR(var);
     155             : 
     156    15030556 :         should_free->var = ret;
     157    15030556 :         ZVAL_DEREF(ret);
     158    15030556 :         return ret;
     159             : }
     160             : 
     161          10 : static zend_never_inline zval *_get_zval_cv_lookup(zval *ptr, uint32_t var, int type, const zend_execute_data *execute_data TSRMLS_DC)
     162             : {
     163             :         zend_string *cv;
     164             : 
     165          10 :         switch (type) {
     166             :                 case BP_VAR_R:
     167             :                 case BP_VAR_UNSET:
     168          10 :                         cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     169          10 :                         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     170             :                         /* break missing intentionally */
     171             :                 case BP_VAR_IS:
     172          10 :                         ptr = &EG(uninitialized_zval);
     173          10 :                         break;
     174             :                 case BP_VAR_RW:
     175           0 :                         cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     176           0 :                         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     177             :                         /* break missing intentionally */
     178             :                 case BP_VAR_W:
     179           0 :                         ZVAL_NULL(ptr);
     180             :                         break;
     181             :         }
     182          10 :         return ptr;
     183             : }
     184             : 
     185             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_R(zval *ptr, uint32_t var, const zend_execute_data *execute_data TSRMLS_DC)
     186             : {
     187         612 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     188             : 
     189         612 :         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     190         612 :         return &EG(uninitialized_zval);
     191             : }
     192             : 
     193             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_UNSET(zval *ptr, uint32_t var, const zend_execute_data *execute_data TSRMLS_DC)
     194             : {
     195           0 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     196             : 
     197           0 :         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     198           0 :         return &EG(uninitialized_zval);
     199             : }
     200             : 
     201             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_RW(zval *ptr, uint32_t var, const zend_execute_data *execute_data TSRMLS_DC)
     202             : {
     203           3 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     204             : 
     205           3 :         ZVAL_NULL(ptr);
     206           3 :         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     207           3 :         return ptr;
     208             : }
     209             : 
     210             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_W(zval *ptr, uint32_t var, const zend_execute_data *execute_data TSRMLS_DC)
     211             : {
     212       38427 :         ZVAL_NULL(ptr);
     213       38427 :         return ptr;
     214             : }
     215             : 
     216             : static zend_always_inline zval *_get_zval_ptr_cv(const zend_execute_data *execute_data, uint32_t var, int type TSRMLS_DC)
     217             : {
     218     1078995 :         zval *ret = EX_VAR(var);
     219             : 
     220     1078995 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     221           9 :                 return _get_zval_cv_lookup(ret, var, type, execute_data TSRMLS_CC);
     222             :         }
     223     1078986 :         return ret;
     224             : }
     225             : 
     226             : static zend_always_inline zval *_get_zval_ptr_cv_deref(const zend_execute_data *execute_data, uint32_t var, int type TSRMLS_DC)
     227             : {
     228     1995956 :         zval *ret = EX_VAR(var);
     229             : 
     230     1995956 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     231           1 :                 return _get_zval_cv_lookup(ret, var, type, execute_data TSRMLS_CC);
     232             :         }
     233     1995955 :         ZVAL_DEREF(ret);
     234     1995955 :         return ret;
     235             : }
     236             : 
     237             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     238             : {
     239    37364667 :         zval *ret = EX_VAR(var);
     240             : 
     241    37364667 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     242         567 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data TSRMLS_CC);
     243             :         }
     244    37364100 :         return ret;
     245             : }
     246             : 
     247             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_R(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     248             : {
     249    16207768 :         zval *ret = EX_VAR(var);
     250             : 
     251    16207768 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     252          45 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data TSRMLS_CC);
     253             :         }
     254    16207723 :         ZVAL_DEREF(ret);
     255    16207723 :         return ret;
     256             : }
     257             : 
     258             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     259             : {
     260       21441 :         zval *ret = EX_VAR(var);
     261             : 
     262       21441 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     263           0 :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data TSRMLS_CC);
     264             :         }
     265       21441 :         return ret;
     266             : }
     267             : 
     268             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     269             : {
     270             :         zval *ret = EX_VAR(var);
     271             : 
     272             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     273             :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data TSRMLS_CC);
     274             :         }
     275             :         ZVAL_DEREF(ret);
     276             :         return ret;
     277             : }
     278             : 
     279             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     280             : {
     281         833 :         zval *ret = EX_VAR(var);
     282             : 
     283         833 :         return ret;
     284             : }
     285             : 
     286             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_IS(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     287             : {
     288      453780 :         zval *ret = EX_VAR(var);
     289             : 
     290      453780 :         ZVAL_DEREF(ret);
     291      453780 :         return ret;
     292             : }
     293             : 
     294             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     295             : {
     296     9539285 :         zval *ret = EX_VAR(var);
     297             : 
     298     9539285 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     299           3 :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data TSRMLS_CC);
     300             :         }
     301     9539282 :         return ret;
     302             : }
     303             : 
     304             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     305             : {
     306             :         zval *ret = EX_VAR(var);
     307             : 
     308             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     309             :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data TSRMLS_CC);
     310             :         }
     311             :         ZVAL_DEREF(ret);
     312             :         return ret;
     313             : }
     314             : 
     315             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     316             : {
     317     7040327 :         zval *ret = EX_VAR(var);
     318             : 
     319     7040327 :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     320       38427 :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data TSRMLS_CC);
     321             :         }
     322     7001900 :         return ret;
     323             : }
     324             : 
     325             : static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     326             : {
     327    17791698 :         return EX_VAR(var);
     328             : }
     329             : 
     330             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var TSRMLS_DC)
     331             : {
     332             :         zval *ret = EX_VAR(var);
     333             : 
     334             :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     335             :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data TSRMLS_CC);
     336             :         }
     337             :         ZVAL_DEREF(ret);
     338             :         return ret;
     339             : }
     340             : 
     341     1181524 : static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
     342             : {
     343             :         zval *ret;
     344             : 
     345     1181524 :         switch (op_type) {
     346             :                 case IS_CONST:
     347      100412 :                         should_free->var = NULL;
     348      100412 :                         return node->zv;
     349             :                         break;
     350             :                 case IS_TMP_VAR:
     351        1639 :                         ret = EX_VAR(node->var);
     352        1639 :                         should_free->var = ret;
     353        1639 :                         return ret;
     354             :                         break;
     355             :                 case IS_VAR:
     356         956 :                         return _get_zval_ptr_var(node->var, execute_data, should_free TSRMLS_CC);
     357             :                         break;
     358             :                 case IS_UNUSED:
     359           0 :                         should_free->var = NULL;
     360           0 :                         return NULL;
     361             :                         break;
     362             :                 case IS_CV:
     363             :                 default:
     364     1078995 :                         should_free->var = NULL;
     365     2157990 :                         return _get_zval_ptr_cv(execute_data, node->var, type TSRMLS_CC);
     366             :                         break;
     367             :         }
     368             :         return NULL;
     369             : }
     370             : 
     371     2871675 : static inline zval *_get_zval_ptr_deref(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
     372             : {
     373             :         zval *ret;
     374             : 
     375     2871675 :         switch (op_type) {
     376             :                 case IS_CONST:
     377      560602 :                         should_free->var = NULL;
     378      560602 :                         return node->zv;
     379             :                         break;
     380             :                 case IS_TMP_VAR:
     381      106534 :                         ret = EX_VAR(node->var);
     382      106534 :                         should_free->var = ret;
     383      106534 :                         return ret;
     384             :                         break;
     385             :                 case IS_VAR:
     386      417166 :                         return _get_zval_ptr_var_deref(node->var, execute_data, should_free TSRMLS_CC);
     387             :                         break;
     388             :                 case IS_UNUSED:
     389           0 :                         should_free->var = NULL;
     390           0 :                         return NULL;
     391             :                         break;
     392             :                 case IS_CV:
     393             :                 default:
     394     1995956 :                         should_free->var = NULL;
     395     3991912 :                         return _get_zval_ptr_cv_deref(execute_data, node->var, type TSRMLS_CC);
     396             :                         break;
     397             :         }
     398             :         return NULL;
     399             : }
     400             : 
     401             : static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
     402             : {
     403     4634993 :         zval *ret = EX_VAR(var);
     404             : 
     405     4634993 :         if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
     406     4633803 :                 should_free->var = NULL;
     407     4633803 :                 return Z_INDIRECT_P(ret);
     408        2309 :         } else if (!Z_REFCOUNTED_P(ret) || Z_REFCOUNT_P(ret) == 1) {
     409         192 :                 should_free->var = ret;
     410         192 :                 return ret;
     411             :         } else {
     412             :                 Z_DELREF_P(ret);
     413         998 :                 should_free->var = NULL;
     414         998 :                 return ret;
     415             :         }
     416             : }
     417             : 
     418             : static inline zval *_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
     419             : {
     420             :         if (op_type == IS_CV) {
     421             :                 should_free->var = NULL;
     422             :                 return _get_zval_ptr_cv(execute_data, node->var, type TSRMLS_CC);
     423             :         } else /* if (op_type == IS_VAR) */ {
     424             :                 ZEND_ASSERT(op_type == IS_VAR);
     425             :                 return _get_zval_ptr_ptr_var(node->var, execute_data, should_free TSRMLS_CC);
     426             :         }
     427             : }
     428             : 
     429             : static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D)
     430             : {
     431      225560 :         if (EXPECTED(Z_OBJ(EG(This)) != NULL)) {
     432      225556 :                 return &EG(This);
     433             :         } else {
     434           4 :                 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     435             :                 return NULL;
     436             :         }
     437             : }
     438             : 
     439             : static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
     440             : {
     441             :         if (op_type == IS_UNUSED) {
     442             :                 if (EXPECTED(Z_OBJ(EG(This)) != NULL)) {
     443             :                         should_free->var = NULL;
     444             :                         return &EG(This);
     445             :                 } else {
     446             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     447             :                 }
     448             :         }
     449             :         return get_zval_ptr(op_type, op, execute_data, should_free, type);
     450             : }
     451             : 
     452             : static inline zval *_get_obj_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
     453             : {
     454             :         if (op_type == IS_UNUSED) {
     455             :                 if (EXPECTED(Z_OBJ(EG(This)) != NULL)) {
     456             :                         should_free->var = NULL;
     457             :                         return &EG(This);
     458             :                 } else {
     459             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     460             :                 }
     461             :         }
     462             :         return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type);
     463             : }
     464             : 
     465      964434 : static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr TSRMLS_DC)
     466             : {
     467      964434 :         if (EXPECTED(variable_ptr != value_ptr)) {
     468     1927714 :                 ZVAL_MAKE_REF(value_ptr);
     469             :                 Z_ADDREF_P(value_ptr);
     470             :                 zval_ptr_dtor(variable_ptr);
     471      963857 :                 ZVAL_REF(variable_ptr, Z_REF_P(value_ptr));
     472             :         } else {
     473        1154 :                 ZVAL_MAKE_REF(variable_ptr);
     474             :         }
     475      964434 : }
     476             : 
     477             : /* this should modify object only if it's empty */
     478        4351 : static inline zval* make_real_object(zval *object_ptr TSRMLS_DC)
     479             : {
     480        4351 :         zval *object = object_ptr;
     481             : 
     482        4351 :         ZVAL_DEREF(object);
     483        4351 :         if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     484          42 :                 if (Z_TYPE_P(object) == IS_NULL
     485             :                         || Z_TYPE_P(object) == IS_FALSE
     486           4 :                         || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
     487             :                         zval_ptr_dtor_nogc(object);
     488          11 :                         object_init(object);
     489          11 :                         zend_error(E_WARNING, "Creating default object from empty value");
     490             :                 }
     491             :         }
     492        4351 :         return object;
     493             : }
     494             : 
     495       88892 : ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, zend_ulong fetch_type, char **class_name, zend_class_entry **pce TSRMLS_DC)
     496             : {
     497             :         zend_string *key;
     498             :         ALLOCA_FLAG(use_heap);
     499             : 
     500       88892 :         STR_ALLOCA_INIT(key, cur_arg_info->class_name, cur_arg_info->class_name_len, use_heap);
     501       88892 :         *pce = zend_fetch_class(key, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
     502       88892 :         STR_ALLOCA_FREE(key, use_heap);
     503             : 
     504       88892 :         *class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name;
     505       88892 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     506         560 :                 return "implement interface ";
     507             :         } else {
     508       88332 :                 return "be an instance of ";
     509             :         }
     510             : }
     511             : 
     512         161 : ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uint32_t arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind, zval *arg TSRMLS_DC)
     513             : {
     514         161 :         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
     515         161 :         const char *fname = zf->common.function_name->val;
     516             :         const char *fsep;
     517             :         const char *fclass;
     518             :         zval old_arg;
     519             : 
     520         161 :         if (zf->common.scope) {
     521          30 :                 fsep =  "::";
     522          30 :                 fclass = zf->common.scope->name->val;
     523             :         } else {
     524         131 :                 fsep =  "";
     525         131 :                 fclass = "";
     526             :         }
     527             : 
     528         161 :         if (arg && zf->common.type == ZEND_USER_FUNCTION) {
     529          24 :                 ZVAL_COPY_VALUE(&old_arg, arg);
     530          24 :                 ZVAL_UNDEF(arg);
     531             :         }
     532             : 
     533         170 :         if (zf->common.type == ZEND_USER_FUNCTION && ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     534          27 :                 zend_error(error_type, "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->func->op_array.filename->val, ptr->opline->lineno);
     535             :         } else {
     536         134 :                 zend_error(error_type, "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);
     537             :         }
     538             : 
     539         101 :         if (arg && zf->common.type == ZEND_USER_FUNCTION) {
     540           8 :                 ZVAL_COPY_VALUE(arg, &old_arg);
     541             :         }
     542         101 : }
     543             : 
     544       90312 : static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zend_ulong fetch_type TSRMLS_DC)
     545             : {
     546             :         zend_arg_info *cur_arg_info;
     547             :         char *need_msg;
     548             :         zend_class_entry *ce;
     549             : 
     550       90312 :         if (UNEXPECTED(!zf->common.arg_info)) {
     551           0 :                 return;
     552             :         }
     553             : 
     554       90312 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     555       90274 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     556          38 :         } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
     557           6 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args-1];
     558             :         } else {
     559          32 :                 return;
     560             :         }
     561             : 
     562       90280 :         if (cur_arg_info->class_name) {
     563             :                 char *class_name;
     564             : 
     565       88930 :                 ZVAL_DEREF(arg);
     566       88930 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     567       88821 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     568       88821 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
     569          75 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg TSRMLS_CC);
     570             :                         }
     571         109 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
     572          69 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     573          69 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg TSRMLS_CC);
     574             :                 }
     575        1350 :         } else if (cur_arg_info->type_hint) {
     576         486 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     577         478 :                         ZVAL_DEREF(arg);
     578         506 :                         if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     579          12 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg TSRMLS_CC);
     580             :                         }
     581           8 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     582           8 :                         if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     583           0 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg TSRMLS_CC);
     584             :                         }
     585             : #if ZEND_DEBUG
     586             :                 } else {
     587             :                         zend_error(E_ERROR, "Unknown typehint");
     588             : #endif
     589             :                 }
     590             :         }
     591             : }
     592             : 
     593           5 : static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_num, zend_ulong fetch_type TSRMLS_DC)
     594             : {
     595             :         zend_arg_info *cur_arg_info;
     596             :         char *need_msg;
     597             :         zend_class_entry *ce;
     598             : 
     599           5 :         if (UNEXPECTED(!zf->common.arg_info)) {
     600           0 :                 return 1;
     601             :         }
     602             : 
     603           5 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     604           5 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     605           0 :         } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
     606           0 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args-1];
     607             :         } else {
     608           0 :                 return 1;
     609             :         }
     610             : 
     611           5 :         if (cur_arg_info->class_name) {
     612             :                 char *class_name;
     613             : 
     614           2 :                 need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
     615           2 :                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "", NULL TSRMLS_CC);
     616           0 :                 return 0;
     617           3 :         } else if (cur_arg_info->type_hint) {
     618           3 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     619           2 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "", NULL TSRMLS_CC);
     620           1 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     621           1 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "", NULL TSRMLS_CC);
     622             : #if ZEND_DEBUG
     623             :                 } else {
     624             :                         zend_error(E_ERROR, "Unknown typehint");
     625             : #endif
     626             :                 }
     627           1 :                 return 0;
     628             :         }
     629           0 :         return 1;
     630             : }
     631             : 
     632          75 : static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t arg_num TSRMLS_DC)
     633             : {
     634          76 :         if (EXPECTED(!(EX(func)->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) ||
     635           5 :             zend_verify_missing_arg_type(EX(func), arg_num, EX(opline)->extended_value TSRMLS_CC)) {
     636          70 :                 const char *class_name = EX(func)->common.scope ? EX(func)->common.scope->name->val : "";
     637          70 :                 const char *space = EX(func)->common.scope ? "::" : "";
     638          70 :                 const char *func_name = EX(func)->common.function_name ? EX(func)->common.function_name->val : "main";
     639          70 :                 zend_execute_data *ptr = EX(prev_execute_data);
     640             : 
     641          85 :                 if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     642          15 :                         zend_error(E_WARNING, "Missing argument %u for %s%s%s(), called in %s on line %d and defined", arg_num, class_name, space, func_name, ptr->func->op_array.filename->val, ptr->opline->lineno);
     643             :                 } else {
     644          55 :                         zend_error(E_WARNING, "Missing argument %u for %s%s%s()", arg_num, class_name, space, func_name);
     645             :                 }
     646             :         }
     647          71 : }
     648             : 
     649      114833 : static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC)
     650             : {
     651             :         zend_free_op free_value;
     652      114833 :         zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R);
     653             :         zval tmp;
     654      114833 :         zval *object = object_ptr;
     655             : 
     656      114833 :         ZVAL_DEREF(object);
     657      114833 :         if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     658          28 :                 if (UNEXPECTED(object == &EG(error_zval))) {
     659           0 :                         if (retval) {
     660           0 :                                 ZVAL_NULL(retval);
     661             :                         }
     662           0 :                         FREE_OP(free_value);
     663           0 :                         return;
     664             :                 }
     665          62 :                 if (EXPECTED(Z_TYPE_P(object) == IS_NULL ||
     666             :                     Z_TYPE_P(object) == IS_FALSE ||
     667             :                     (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
     668             :                         zend_object *obj;
     669             : 
     670             :                         zval_ptr_dtor(object);
     671          24 :                         object_init(object);
     672             :                         Z_ADDREF_P(object);
     673          24 :                         obj = Z_OBJ_P(object);
     674          24 :                         zend_error(E_WARNING, "Creating default object from empty value");
     675          24 :                         if (GC_REFCOUNT(obj) == 1) {
     676             :                                 /* the enclosing container was deleted, obj is unreferenced */
     677           1 :                                 if (retval) {
     678           1 :                                         ZVAL_NULL(retval);
     679             :                                 }
     680           1 :                                 FREE_OP(free_value);
     681           1 :                                 OBJ_RELEASE(obj);
     682           1 :                                 return;
     683             :                         }
     684             :                         Z_DELREF_P(object);
     685             :                 } else {
     686           4 :                         zend_error(E_WARNING, "Attempt to assign property of non-object");
     687           4 :                         if (retval) {
     688           0 :                                 ZVAL_NULL(retval);
     689             :                         }
     690           4 :                         FREE_OP(free_value);
     691           4 :                         return;
     692             :                 }
     693             :         }
     694             : 
     695             :         /* separate our value if necessary */
     696      114828 :         if (value_type == IS_TMP_VAR) {
     697         545 :                 ZVAL_COPY_VALUE(&tmp, value);
     698         545 :                 value = &tmp;
     699      114283 :         } else if (value_type == IS_CONST) {
     700      100331 :                 if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
     701          70 :                         ZVAL_COPY_VALUE(&tmp, value);
     702          70 :                         zval_copy_ctor_func(&tmp);
     703          70 :                         value = &tmp;
     704             :                 }
     705       13952 :         } else if (Z_REFCOUNTED_P(value)) {
     706             :                 Z_ADDREF_P(value);
     707             :         }
     708             : 
     709      114828 :         if (opcode == ZEND_ASSIGN_OBJ) {
     710      113273 :                 if (!Z_OBJ_HT_P(object)->write_property) {
     711           0 :                         zend_error(E_WARNING, "Attempt to assign property of non-object");
     712           0 :                         if (retval) {
     713           0 :                                 ZVAL_NULL(retval);
     714             :                         }
     715           0 :                         if (value_type == IS_CONST) {
     716             :                                 zval_ptr_dtor(value);
     717             :                         }
     718           0 :                         FREE_OP(free_value);
     719           0 :                         return;
     720             :                 }
     721      113273 :                 Z_OBJ_HT_P(object)->write_property(object, property_name, value, cache_slot TSRMLS_CC);
     722             :         } else {
     723             :                 /* Note:  property_name in this case is really the array index! */
     724        1555 :                 if (!Z_OBJ_HT_P(object)->write_dimension) {
     725           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
     726             :                 }
     727        1555 :                 Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
     728             :         }
     729             : 
     730      114818 :         if (retval && !EG(exception)) {
     731          30 :                 ZVAL_COPY(retval, value);
     732             :         }
     733             :         zval_ptr_dtor(value);
     734      114818 :         if (value_type == IS_VAR) {
     735         451 :                 FREE_OP(free_value);
     736             :         }
     737             : }
     738             : 
     739         145 : static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result TSRMLS_DC)
     740             : {
     741             :         zend_string *old_str;
     742             : 
     743         145 :         if (offset < 0) {
     744           1 :                 zend_error(E_WARNING, "Illegal string offset:  " ZEND_LONG_FMT, offset);
     745           1 :                 zend_string_release(Z_STR_P(str));
     746           1 :                 if (result) {
     747           0 :                         ZVAL_NULL(result);
     748             :                 }
     749           1 :                 return;
     750             :         }
     751             : 
     752         144 :         old_str = Z_STR_P(str);
     753         144 :         if ((size_t)offset >= Z_STRLEN_P(str)) {
     754           3 :                 zend_long old_len = Z_STRLEN_P(str);
     755           6 :                 Z_STR_P(str) = zend_string_realloc(Z_STR_P(str), offset + 1, 0);
     756           3 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
     757           3 :                 memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
     758           3 :                 Z_STRVAL_P(str)[offset+1] = 0;
     759         141 :         } else if (!Z_REFCOUNTED_P(str)) {
     760          16 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
     761           8 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
     762             :         }
     763             : 
     764         144 :         if (Z_TYPE_P(value) != IS_STRING) {
     765          11 :                 zend_string *tmp = zval_get_string(value);
     766             : 
     767          11 :                 Z_STRVAL_P(str)[offset] = tmp->val[0];
     768             :                 zend_string_release(tmp);
     769             :         } else {
     770         133 :                 Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
     771             :         }
     772             :         /*
     773             :          * the value of an assignment to a string offset is undefined
     774             :         T(result->u.var).var = &T->str_offset.str;
     775             :         */
     776             : 
     777             :         zend_string_release(old_str);
     778         144 :         if (result) {
     779          12 :                 zend_uchar c = (zend_uchar)Z_STRVAL_P(str)[offset];
     780             : 
     781          12 :                 if (CG(one_char_string)[c]) {
     782           0 :                         ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
     783             :                 } else {
     784          24 :                         ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(str) + offset, 1, 0));
     785             :                 }
     786             :         }
     787             : }
     788             : 
     789             : static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC)
     790             : {
     791             :         do {
     792    19652677 :                 if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { 
     793             :                         zend_refcounted *garbage;
     794             : 
     795    11815216 :                         if (Z_ISREF_P(variable_ptr)) {
     796     2778049 :                                 variable_ptr = Z_REFVAL_P(variable_ptr);
     797     2778049 :                                 if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) {
     798             :                                         break;
     799             :                                 }
     800             :                         }
     801    10843603 :                         if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
     802      805194 :                         UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
     803           0 :                                 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC);
     804           0 :                                 return variable_ptr;
     805             :                         }
     806    10038409 :                         if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) {
     807         120 :                                 return variable_ptr;
     808             :                         }
     809    10038289 :                         garbage = Z_COUNTED_P(variable_ptr);
     810    10038289 :                         if (--GC_REFCOUNT(garbage) == 0) {
     811     5373980 :                                 ZVAL_COPY_VALUE(variable_ptr, value);
     812     5373980 :                                 if (value_type == IS_CONST) {
     813             :                                         /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
     814       22218 :                                         if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) {
     815       13523 :                                                 zval_copy_ctor_func(variable_ptr);
     816             :                                         }
     817     5351762 :                                 } else if (value_type != IS_TMP_VAR) {
     818     5271097 :                                         if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) {
     819             :                                                 Z_ADDREF_P(variable_ptr);
     820             :                                         }
     821             :                                 }
     822     5373980 :                                 _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
     823     5373976 :                                 return variable_ptr;
     824             :                         } else { /* we need to split */
     825             :                                 /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */
     826     4891643 :                                 if ((Z_COLLECTABLE_P(variable_ptr)) &&
     827      227334 :                                 UNEXPECTED(!GC_INFO(garbage))) {
     828       18217 :                                         gc_possible_root(garbage TSRMLS_CC);
     829             :                                 }
     830             :                         }
     831             :                 }
     832             :         } while (0);
     833             : 
     834    14278577 :         ZVAL_COPY_VALUE(variable_ptr, value);
     835    14278577 :         if (value_type == IS_CONST) {
     836             :                 /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */
     837     3086395 :                 if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) {
     838      203002 :                         zval_copy_ctor_func(variable_ptr);
     839             :                 }
     840    11192182 :         } else if (value_type != IS_TMP_VAR) {
     841     8379910 :                 if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) {
     842             :                         Z_ADDREF_P(variable_ptr);
     843             :                 }
     844             :         }
     845    14278577 :         return variable_ptr;
     846             : }
     847             : 
     848             : /* Utility Functions for Extensions */
     849           0 : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     850             : {
     851           0 :         if (extension->statement_handler) {
     852           0 :                 extension->statement_handler(op_array);
     853             :         }
     854           0 : }
     855             : 
     856             : 
     857           0 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     858             : {
     859           0 :         if (extension->fcall_begin_handler) {
     860           0 :                 extension->fcall_begin_handler(op_array);
     861             :         }
     862           0 : }
     863             : 
     864             : 
     865           0 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
     866             : {
     867           0 :         if (extension->fcall_end_handler) {
     868           0 :                 extension->fcall_end_handler(op_array);
     869             :         }
     870           0 : }
     871             : 
     872             : 
     873             : static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_data *execute_data, int fetch_type TSRMLS_DC)
     874             : {
     875             :         HashTable *ht;
     876             : 
     877      214460 :         if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) || 
     878      107230 :             EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
     879       13370 :                 ht = &EG(symbol_table).ht;
     880       93860 :         } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
     881             :                 ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
     882        1384 :                 ht = EX(func)->op_array.static_variables;
     883             :         } else {
     884             :                 ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
     885       92476 :                 if (!EX(symbol_table)) {
     886       87388 :                         zend_rebuild_symbol_table(TSRMLS_C);
     887             :                 }
     888       92476 :                 ht = &EX(symbol_table)->ht;
     889             :         }
     890      107230 :         return ht;
     891             : }
     892             : 
     893             : static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
     894             : {
     895             :         zval *retval;
     896             :         zend_string *offset_key;
     897             :         zend_ulong hval;
     898             : 
     899     8737702 :         if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
     900     5087697 :                 hval = Z_LVAL_P(dim);
     901             : num_index:
     902     5267840 :                 retval = zend_hash_index_find(ht, hval);
     903     5267840 :                 if (retval == NULL) {
     904      396065 :                         switch (type) {
     905             :                                 case BP_VAR_R:
     906          16 :                                         zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
     907             :                                         /* break missing intentionally */
     908             :                                 case BP_VAR_UNSET:
     909             :                                 case BP_VAR_IS:
     910          18 :                                         retval = &EG(uninitialized_zval);
     911             :                                         break;
     912             :                                 case BP_VAR_RW:
     913           6 :                                         zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
     914             :                                         /* break missing intentionally */
     915             :                                 case BP_VAR_W:
     916      396047 :                                         retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
     917             :                                         break;
     918             :                         }
     919             :                 }
     920     3650005 :         } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
     921     3649931 :                 offset_key = Z_STR_P(dim);
     922     3649931 :                 if (dim_type != IS_CONST) {
     923     5975122 :                         if (ZEND_HANDLE_NUMERIC(offset_key, hval)) {
     924             :                                 goto num_index;
     925             :                         }
     926             :                 }
     927             : str_index:
     928     3469856 :                 retval = zend_hash_find(ht, offset_key);
     929     3469856 :                 if (retval) {
     930             :                         /* support for $GLOBALS[...] */
     931     1562497 :                         if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
     932        7804 :                                 retval = Z_INDIRECT_P(retval);
     933        7804 :                                 if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
     934          21 :                                         switch (type) {
     935             :                                                 case BP_VAR_R:
     936           1 :                                                         zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
     937             :                                                         /* break missing intentionally */
     938             :                                                 case BP_VAR_UNSET:
     939             :                                                 case BP_VAR_IS:
     940           1 :                                                         retval = &EG(uninitialized_zval);
     941             :                                                         break;
     942             :                                                 case BP_VAR_RW:
     943           0 :                                                         zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
     944             :                                                         /* break missing intentionally */
     945             :                                                 case BP_VAR_W:
     946          20 :                                                         ZVAL_NULL(retval);
     947             :                                                         break;
     948             :                                         }
     949             :                                 }
     950             :                         }
     951             :                 } else { 
     952     1907359 :                         switch (type) {
     953             :                                 case BP_VAR_R:
     954      156175 :                                         zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
     955             :                                         /* break missing intentionally */
     956             :                                 case BP_VAR_UNSET:
     957             :                                 case BP_VAR_IS:
     958      156175 :                                         retval = &EG(uninitialized_zval);
     959             :                                         break;
     960             :                                 case BP_VAR_RW:
     961           1 :                                         zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
     962             :                                         /* break missing intentionally */
     963             :                                 case BP_VAR_W:
     964     1751184 :                                         retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
     965             :                                         break;
     966             :                         }
     967             :                 }
     968             :         } else {
     969          74 :                 switch (Z_TYPE_P(dim)) {
     970             :                         case IS_NULL:
     971          10 :                                 offset_key = STR_EMPTY_ALLOC();
     972             :                                 goto str_index;
     973             :                         case IS_DOUBLE:
     974          92 :                                 hval = zend_dval_to_lval(Z_DVAL_P(dim));
     975             :                                 goto num_index;
     976             :                         case IS_RESOURCE:
     977           3 :                                 zend_error(E_STRICT, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
     978           3 :                                 hval = Z_RES_HANDLE_P(dim);
     979             :                                 goto num_index;
     980             :                         case IS_FALSE:
     981           6 :                                 hval = 0;
     982             :                                 goto num_index;
     983             :                         case IS_TRUE:
     984           3 :                                 hval = 1;
     985             :                                 goto num_index;
     986             :                         default:
     987           6 :                                 zend_error(E_WARNING, "Illegal offset type");
     988           6 :                                 retval = (type == BP_VAR_W || type == BP_VAR_RW) ?
     989             :                                         &EG(error_zval) : &EG(uninitialized_zval);
     990             :                 }
     991             :         }
     992     8737702 :         return retval;
     993             : }
     994             : 
     995             : static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref, int allow_str_offset TSRMLS_DC)
     996             : {
     997             :     zval *retval;
     998     4454864 :     zval *container = container_ptr;
     999             : 
    1000     4454864 :         ZVAL_DEREF(container);
    1001     4454864 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1002     9007960 :                 SEPARATE_ARRAY(container);
    1003             : fetch_from_array:
    1004     4454641 :                 if (dim == NULL) {
    1005      564318 :                         retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
    1006      564318 :                         if (UNEXPECTED(retval == NULL)) {
    1007           1 :                                 zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
    1008           1 :                                 retval = &EG(error_zval);
    1009             :                         }
    1010             :                 } else {
    1011     7780646 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
    1012             :                 }
    1013     4454641 :                 if (is_ref) {
    1014      179874 :                         ZVAL_MAKE_REF(retval);
    1015             :                 }
    1016     4454641 :                 ZVAL_INDIRECT(result, retval);
    1017        1328 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1018             :                 zend_long offset;
    1019             : 
    1020         156 :                 if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
    1021             :                         zval_ptr_dtor_nogc(container);
    1022             : convert_to_array:
    1023        1105 :                         ZVAL_NEW_ARR(container);
    1024        1105 :                         zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
    1025             :                         goto fetch_from_array;
    1026             :                 }
    1027             : 
    1028         152 :                 if (dim == NULL) {
    1029           0 :                         zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
    1030             :                 }
    1031             : 
    1032         152 :                 if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1033          15 :                         switch(Z_TYPE_P(dim)) {
    1034             :                                 case IS_STRING:
    1035          30 :                                         if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1036             :                                                 break;
    1037             :                                         }
    1038          15 :                                         if (type != BP_VAR_UNSET) {
    1039          14 :                                                 zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1040             :                                         }
    1041             :                                         break;
    1042             :                                 case IS_DOUBLE:
    1043             :                                 case IS_NULL:
    1044             :                                 case IS_FALSE:
    1045             :                                 case IS_TRUE:
    1046           0 :                                         zend_error(E_NOTICE, "String offset cast occurred");
    1047             :                                         break;
    1048             :                                 default:
    1049           0 :                                         zend_error(E_WARNING, "Illegal offset type");
    1050             :                                         break;
    1051             :                         }
    1052             : 
    1053          15 :                         offset = zval_get_long(dim);
    1054             :                 } else {
    1055         137 :                         offset = Z_LVAL_P(dim);
    1056             :                 }
    1057             : 
    1058         152 :                 if (allow_str_offset) {
    1059         145 :                         if (Z_REFCOUNTED_P(container)) {
    1060         136 :                                 if (Z_REFCOUNT_P(container) > 1) {
    1061             :                                         Z_DELREF_P(container);
    1062           6 :                                         zval_copy_ctor_func(container);
    1063             :                                 }
    1064             :                                 Z_ADDREF_P(container);
    1065             :                         }
    1066         145 :                         ZVAL_LONG(result, offset);
    1067         145 :                         return container; /* assignment to string offset */
    1068             :                 } else {
    1069           7 :                         ZVAL_INDIRECT(result, NULL); /* wrong string offset */
    1070             :                 }
    1071        1172 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1072          51 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1073           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1074             :                 } else {
    1075          51 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result TSRMLS_CC);
    1076             : 
    1077          51 :                         if (UNEXPECTED(retval == &EG(uninitialized_zval))) {
    1078           2 :                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1079             : 
    1080           2 :                                 ZVAL_NULL(result);
    1081           2 :                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
    1082          95 :                         } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) {
    1083          46 :                                 if (!Z_ISREF_P(retval)) {
    1084          76 :                                         if (Z_REFCOUNTED_P(retval) &&
    1085             :                                             Z_REFCOUNT_P(retval) > 1) {
    1086           7 :                                                 if (Z_TYPE_P(retval) != IS_OBJECT) {
    1087             :                                                         Z_DELREF_P(retval);
    1088           5 :                                                         ZVAL_DUP(result, retval);
    1089           5 :                                                         retval = result;
    1090             :                                                 } else {
    1091           2 :                                                         ZVAL_COPY(result, retval);
    1092           2 :                                                         retval = result;
    1093             :                                                 }
    1094             :                                         }
    1095          40 :                                         if (Z_TYPE_P(retval) != IS_OBJECT) {
    1096           9 :                                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1097           9 :                                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
    1098             :                                         }
    1099             :                                 }
    1100          46 :                                 if (result != retval) {
    1101           5 :                                         if (is_ref) {
    1102           0 :                                                 ZVAL_MAKE_REF(retval);
    1103             :                                         }
    1104           5 :                                         ZVAL_INDIRECT(result, retval);
    1105             :                                 }
    1106             :                         } else {
    1107           3 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1108             :                         }
    1109             :                 }
    1110        1121 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_NULL)) {
    1111        1098 :                 if (UNEXPECTED(container == &EG(error_zval))) {
    1112           1 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1113        1097 :                 } else if (type != BP_VAR_UNSET) {
    1114             :                         goto convert_to_array;
    1115             :                 } else {
    1116             :                         /* for read-mode only */
    1117           0 :                         ZVAL_NULL(result);
    1118             :                 }
    1119             :         } else {
    1120          46 :                 if (type != BP_VAR_UNSET &&
    1121             :                     Z_TYPE_P(container) == IS_FALSE) {
    1122             :                         goto convert_to_array;
    1123             :                 }
    1124          19 :                 if (type == BP_VAR_UNSET) {
    1125           0 :                         zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
    1126           0 :                         ZVAL_NULL(result);
    1127             :                 } else {
    1128          19 :                         zend_error(E_WARNING, "Cannot use a scalar value as an array");
    1129          19 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1130             :                 }
    1131             :         }
    1132     4454719 :         return NULL; /* not an assignment to string offset */
    1133             : }
    1134             : 
    1135      232282 : static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
    1136             : {
    1137             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 0 TSRMLS_CC);
    1138      232282 : }
    1139             : 
    1140     2871512 : static zend_never_inline zval *zend_fetch_dimension_address_W_str(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
    1141             : {
    1142     2871512 :         return zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 1 TSRMLS_CC);
    1143             : }
    1144             : 
    1145       89939 : static zend_never_inline void zend_fetch_dimension_address_W_ref(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
    1146             : {
    1147             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1, 0 TSRMLS_CC);
    1148       89939 : }
    1149             : 
    1150     1261111 : static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
    1151             : {
    1152             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0, 0 TSRMLS_CC);
    1153     1261111 : }
    1154             : 
    1155          20 : static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
    1156             : {
    1157             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0, 0 TSRMLS_CC);
    1158          20 : }
    1159             : 
    1160             : static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
    1161             : {
    1162             :         zval *retval;
    1163             : 
    1164     4880435 :         ZVAL_DEREF(container);
    1165     4880435 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1166     9694644 :                 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
    1167     4847322 :                 ZVAL_COPY(result, retval);
    1168       33113 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1169             :                 zend_long offset;
    1170             : 
    1171       32158 :                 if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1172          46 :                         switch(Z_TYPE_P(dim)) {
    1173             :                                 /* case IS_LONG: */
    1174             :                                 case IS_STRING:
    1175          60 :                                         if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1176             :                                                 break;
    1177             :                                         }
    1178          29 :                                         if (type != BP_VAR_IS) {
    1179          21 :                                                 zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1180             :                                         }
    1181             :                                         break;
    1182             :                                 case IS_DOUBLE:
    1183             :                                 case IS_NULL:
    1184             :                                 case IS_FALSE:
    1185             :                                 case IS_TRUE:
    1186          13 :                                         if (type != BP_VAR_IS) {
    1187          11 :                                                 zend_error(E_NOTICE, "String offset cast occurred");
    1188             :                                         }
    1189             :                                         break;
    1190             :                                 default:
    1191           3 :                                         zend_error(E_WARNING, "Illegal offset type");
    1192             :                                         break;
    1193             :                         }
    1194             : 
    1195          46 :                         offset = zval_get_long(dim);
    1196             :                 } else {
    1197       32112 :                         offset = Z_LVAL_P(dim);
    1198             :                 }
    1199             : 
    1200       32158 :                 if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) {
    1201          43 :                         if (type != BP_VAR_IS) {
    1202          39 :                                 zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset);
    1203             :                         }
    1204          43 :                         ZVAL_EMPTY_STRING(result);
    1205             :                 } else {
    1206       32115 :                         zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset];
    1207             : 
    1208       32115 :                         if (CG(one_char_string)[c]) {
    1209           0 :                                 ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1210             :                         } else {
    1211       64230 :                                 ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(container) + offset, 1, 0));
    1212             :                         }
    1213             :                 }
    1214         955 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1215         754 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1216           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1217             :                 } else {
    1218         754 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result TSRMLS_CC);
    1219             : 
    1220         750 :                         if (result) {
    1221         750 :                                 if (retval) {
    1222         742 :                                         if (result != retval) {
    1223         122 :                                                 ZVAL_COPY(result, retval);
    1224             :                                         }
    1225             :                                 } else {
    1226           8 :                                         ZVAL_NULL(result);
    1227             :                                 }
    1228             :                         }
    1229             :                 }
    1230             :         } else {
    1231         201 :                 ZVAL_NULL(result);
    1232             :         }
    1233             : }
    1234             : 
    1235     4879566 : static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type TSRMLS_DC)
    1236             : {
    1237             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R TSRMLS_CC);
    1238     4879562 : }
    1239             : 
    1240         869 : static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type TSRMLS_DC)
    1241             : {
    1242             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS TSRMLS_CC);
    1243         869 : }
    1244             : 
    1245          11 : ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim TSRMLS_DC)
    1246             : {
    1247          11 :         zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC);
    1248          11 : }
    1249             : 
    1250      175480 : static void zend_fetch_property_address(zval *result, zval *container_ptr, zval *prop_ptr, void **cache_slot, int type, int is_ref TSRMLS_DC)
    1251             : {
    1252      175480 :         zval *container = container_ptr;
    1253             : 
    1254      175480 :         ZVAL_DEREF(container);
    1255      175480 :         if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
    1256          44 :                 if (UNEXPECTED(container == &EG(error_zval))) {
    1257           1 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1258           1 :                         return;
    1259             :                 }
    1260             : 
    1261             :                 /* this should modify object only if it's empty */
    1262         138 :                 if (type != BP_VAR_UNSET &&
    1263           3 :                     EXPECTED((Z_TYPE_P(container) == IS_NULL ||
    1264             :                       Z_TYPE_P(container) == IS_FALSE ||
    1265             :                       (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
    1266             :                         zval_ptr_dtor_nogc(container);
    1267          37 :                         object_init(container);
    1268             :                 } else {
    1269           6 :                         zend_error(E_WARNING, "Attempt to modify property of non-object");
    1270           6 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1271           6 :                         return;
    1272             :                 }
    1273             :         }
    1274             : 
    1275      175473 :         if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
    1276      175473 :                 zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC);
    1277      175472 :                 if (NULL == ptr) {
    1278         168 :                         if (Z_OBJ_HT_P(container)->read_property &&
    1279          56 :                                 (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC)) != NULL) {
    1280          56 :                                 if (ptr != result) {
    1281           3 :                                         if (is_ref && ptr != &EG(uninitialized_zval)) {
    1282           0 :                                                 ZVAL_MAKE_REF(ptr);
    1283             :                                         }
    1284           3 :                                         ZVAL_INDIRECT(result, ptr);
    1285             :                                 }
    1286             :                         } else {
    1287           0 :                                 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
    1288             :                         }
    1289             :                 } else {
    1290      175416 :                         if (is_ref) {
    1291         146 :                                 ZVAL_MAKE_REF(ptr);
    1292             :                         }
    1293      175416 :                         ZVAL_INDIRECT(result, ptr);
    1294             :                 }
    1295           0 :         } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
    1296           0 :                 zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC);
    1297           0 :                 if (ptr != result) {
    1298           0 :                         if (is_ref && ptr != &EG(uninitialized_zval)) {
    1299           0 :                                 ZVAL_MAKE_REF(ptr);
    1300             :                         }
    1301           0 :                         ZVAL_INDIRECT(result, ptr);
    1302             :                 }
    1303             :         } else {
    1304           0 :                 zend_error(E_WARNING, "This object doesn't support property references");
    1305           0 :                 ZVAL_INDIRECT(result, &EG(error_zval));
    1306             :         }
    1307             : }
    1308             : 
    1309       78140 : static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const zend_execute_data *execute_data TSRMLS_DC)
    1310             : {
    1311       78140 :         int original_nest_levels = nest_levels;
    1312             :         zend_brk_cont_element *jmp_to;
    1313             : 
    1314             :         do {
    1315       78298 :                 if (array_offset==-1) {
    1316           1 :                         zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
    1317             :                 }
    1318       78297 :                 jmp_to = &op_array->brk_cont_array[array_offset];
    1319       78297 :                 if (nest_levels>1) {
    1320         158 :                         zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
    1321             : 
    1322         158 :                         if (brk_opline->opcode == ZEND_FREE) {
    1323           3 :                                 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
    1324           1 :                                         zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
    1325             :                                 }
    1326             :                         }
    1327             :                 }
    1328       78297 :                 array_offset = jmp_to->parent;
    1329       78297 :         } while (--nest_levels > 0);
    1330       78139 :         return jmp_to;
    1331             : }
    1332             : 
    1333             : #if ZEND_INTENSIVE_DEBUGGING
    1334             : 
    1335             : #define CHECK_SYMBOL_TABLES()                                                                                                   \
    1336             :         zend_hash_apply(&EG(symbol_table), zend_check_symbol TSRMLS_CC);                    \
    1337             :         if (&EG(symbol_table)!=EX(symbol_table)) {                                                  \
    1338             :                 zend_hash_apply(EX(symbol_table), zend_check_symbol TSRMLS_CC); \
    1339             :         }
    1340             : 
    1341             : static int zend_check_symbol(zval *pz TSRMLS_DC)
    1342             : {
    1343             :         if (Z_TYPE_P(pz) == IS_INDIRECT) {
    1344             :                 pz = Z_INDIRECT_P(pz);
    1345             :         }
    1346             :         if (Z_TYPE_P(pz) > 10) {
    1347             :                 fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
    1348             : /* See http://support.microsoft.com/kb/190351 */
    1349             : #ifdef PHP_WIN32
    1350             :                 fflush(stderr);
    1351             : #endif
    1352             :         } else if (Z_TYPE_P(pz) == IS_ARRAY) {
    1353             :                 zend_hash_apply(Z_ARRVAL_P(pz), zend_check_symbol TSRMLS_CC);
    1354             :         } else if (Z_TYPE_P(pz) == IS_OBJECT) {
    1355             :                 /* OBJ-TBI - doesn't support new object model! */
    1356             :                 zend_hash_apply(Z_OBJPROP_P(pz), zend_check_symbol TSRMLS_CC);
    1357             :         }
    1358             : 
    1359             :         return 0;
    1360             : }
    1361             : 
    1362             : 
    1363             : #else
    1364             : #define CHECK_SYMBOL_TABLES()
    1365             : #endif
    1366             : 
    1367             : ZEND_API opcode_handler_t *zend_opcode_handlers;
    1368             : 
    1369           0 : ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC)
    1370             : {
    1371           0 :         execute_data->func->internal_function.handler(execute_data->num_args, return_value TSRMLS_CC);
    1372           0 : }
    1373             : 
    1374       87820 : void zend_clean_and_cache_symbol_table(zend_array *symbol_table TSRMLS_DC) /* {{{ */
    1375             : {
    1376       87820 :         if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
    1377           0 :                 zend_hash_destroy(&symbol_table->ht);
    1378           0 :                 FREE_HASHTABLE(symbol_table);
    1379             :         } else {
    1380             :                 /* clean before putting into the cache, since clean
    1381             :                    could call dtors, which could use cached hash */
    1382       87820 :                 zend_hash_clean(&symbol_table->ht);
    1383       87820 :                 *(++EG(symtable_cache_ptr)) = symbol_table;
    1384             :         }
    1385       87820 : }
    1386             : /* }}} */
    1387             : 
    1388             : static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
    1389             : {
    1390     2052893 :         if (EXPECTED(EX(func)->op_array.last_var > 0)) {
    1391     1848170 :                 zval *cv = EX_VAR_NUM(0);
    1392     1848170 :                 zval *end = cv + EX(func)->op_array.last_var;
    1393             :                 do {
    1394             :                         zval_ptr_dtor(cv);
    1395     9932067 :                         cv++;
    1396     9932067 :                 } while (cv != end);
    1397             :         }
    1398             : }
    1399             : /* }}} */
    1400             : 
    1401          82 : void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
    1402             : {
    1403             :         i_free_compiled_variables(execute_data TSRMLS_CC);
    1404          82 : }
    1405             : /* }}} */
    1406             : 
    1407             : /*
    1408             :  * Stack Frame Layout (the whole stack frame is allocated at once)
    1409             :  * ==================
    1410             :  *
    1411             :  *                             +========================================+
    1412             :  * EG(current_execute_data) -> | zend_execute_data                      |
    1413             :  *                             +----------------------------------------+
    1414             :  *     EX_CV_NUM(0) ---------> | VAR[0] = ARG[1]                        |
    1415             :  *                             | ...                                    |
    1416             :  *                             | VAR[op_array->num_args-1] = ARG[N]     |
    1417             :  *                             | ...                                    |
    1418             :  *                             | VAR[op_array->last_var-1]              |
    1419             :  *                             | VAR[op_array->last_var] = TMP[0]       |
    1420             :  *                             | ...                                    |
    1421             :  *                             | VAR[op_array->last_var+op_array->T-1]  |
    1422             :  *                             | ARG[N+1] (extra_args)                  |
    1423             :  *                             | ...                                    |
    1424             :  *                             +----------------------------------------+
    1425             :  */
    1426             : 
    1427             : static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
    1428             : {
    1429             :         uint32_t first_extra_arg, num_args;
    1430             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1431             :         ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
    1432             : 
    1433     1585505 :         EX(opline) = op_array->opcodes;
    1434     1585505 :         EX(call) = NULL;
    1435     1585505 :         EX(frame_kind) = frame_kind;
    1436     1585505 :         EX(return_value) = return_value;
    1437     1585505 :         EX(scope) = EG(scope);
    1438     1585505 :         EX(delayed_exception) = NULL;
    1439     1585505 :         ZVAL_UNDEF(&EX(old_error_reporting));
    1440             : 
    1441             :         /* Handle arguments */
    1442     1585505 :         first_extra_arg = op_array->num_args;
    1443     1585505 :         if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) {
    1444          45 :                 first_extra_arg--;
    1445             :         }
    1446     1585505 :         num_args = EX(num_args);
    1447     1585505 :         if (UNEXPECTED(num_args > first_extra_arg)) {
    1448             :                 zval *end, *src, *dst;
    1449             : 
    1450          92 :                 if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1451             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1452          89 :                         EX(opline) += first_extra_arg;
    1453             :                 }
    1454             : 
    1455             :                 /* move extra args into separate array after all CV and TMP vars */
    1456          92 :                 end = EX_VAR_NUM(first_extra_arg - 1);
    1457          92 :                 src = end + (num_args - first_extra_arg);
    1458          92 :                 dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    1459          92 :                 if (EXPECTED(src != dst)) {
    1460             :                         do {
    1461       20167 :                                 ZVAL_COPY_VALUE(dst, src);
    1462       20167 :                                 ZVAL_UNDEF(src);
    1463       20167 :                                 src--;
    1464       20167 :                                 dst--;
    1465       20167 :                         } while (src != end);
    1466             :                 }
    1467     1585413 :         } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1468             :                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1469     1497406 :                 EX(opline) += num_args;
    1470             :         }
    1471             : 
    1472             :         /* Initialize CV variables (skip arguments) */
    1473     1585505 :         if (EXPECTED(num_args < op_array->last_var)) {
    1474      768621 :                 zval *var = EX_VAR_NUM(num_args);
    1475      768621 :                 zval *end = EX_VAR_NUM(op_array->last_var);
    1476             : 
    1477             :                 do {
    1478     4323590 :                         ZVAL_UNDEF(var);
    1479     4323590 :                         var++;
    1480     4323590 :                 } while (var != end);
    1481             :         }
    1482             : 
    1483     1585505 :         if (op_array->this_var != -1 && EX(object)) {
    1484       97804 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), EX(object));
    1485       97804 :                 GC_REFCOUNT(EX(object))++;
    1486             :         }
    1487             : 
    1488     1585505 :         if (!op_array->run_time_cache && op_array->last_cache_slot) {
    1489       13780 :                 op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
    1490             :         }
    1491     1585505 :         EX(run_time_cache) = op_array->run_time_cache;
    1492             : 
    1493     1585505 :         EG(current_execute_data) = execute_data;
    1494             : }
    1495             : /* }}} */
    1496             : 
    1497             : static zend_always_inline void i_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
    1498             : {
    1499             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1500             :         ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
    1501             : 
    1502        8962 :         EX(opline) = op_array->opcodes;
    1503        8962 :         EX(call) = NULL;
    1504        8962 :         EX(frame_kind) = frame_kind;
    1505        8962 :         EX(return_value) = return_value;
    1506        8962 :         EX(scope) = EG(scope);
    1507        8962 :         EX(delayed_exception) = NULL;
    1508        8962 :         ZVAL_UNDEF(&EX(old_error_reporting));
    1509             : 
    1510        8962 :         zend_attach_symbol_table(execute_data);
    1511             : 
    1512        8962 :         if (!op_array->run_time_cache && op_array->last_cache_slot) {
    1513        7848 :                 op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
    1514             :         }
    1515        8962 :         EX(run_time_cache) = op_array->run_time_cache;
    1516             : 
    1517        8962 :         EG(current_execute_data) = execute_data;
    1518             : }
    1519             : /* }}} */
    1520             : 
    1521             : static zend_always_inline void i_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
    1522             : {
    1523             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1524             :         ZEND_ASSERT(EX(object) == Z_OBJ(EG(This)));
    1525             : 
    1526      487747 :         EX(opline) = op_array->opcodes;
    1527      487747 :         EX(call) = NULL;
    1528      487747 :         EX(frame_kind) = frame_kind;
    1529      487747 :         EX(return_value) = return_value;
    1530      487747 :         EX(scope) = EG(scope);
    1531      487747 :         EX(delayed_exception) = NULL;
    1532      487747 :         ZVAL_UNDEF(&EX(old_error_reporting));
    1533             : 
    1534      487747 :         if (UNEXPECTED(EX(symbol_table) != NULL)) {
    1535       20217 :                 zend_attach_symbol_table(execute_data);
    1536             :         } else {
    1537             :                 uint32_t first_extra_arg, num_args;
    1538             :                 
    1539             :                 /* Handle arguments */
    1540      467530 :                 first_extra_arg = op_array->num_args;
    1541      467530 :                 if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_VARIADIC) != 0)) {
    1542           0 :                         first_extra_arg--;
    1543             :                 }
    1544      467530 :                 num_args = EX(num_args);
    1545      467530 :                 if (UNEXPECTED(num_args > first_extra_arg)) {
    1546             :                         zval *end, *src, *dst;
    1547             : 
    1548         777 :                         if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1549             :                                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1550         775 :                                 EX(opline) += first_extra_arg;
    1551             :                         }
    1552             : 
    1553             :                         /* move extra args into separate array after all CV and TMP vars */
    1554         777 :                         end = EX_VAR_NUM(first_extra_arg - 1);
    1555         777 :                         src = end + (num_args - first_extra_arg);
    1556         777 :                         dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    1557         777 :                         if (EXPECTED(src != dst)) {
    1558             :                                 do {
    1559         717 :                                         ZVAL_COPY_VALUE(dst, src);
    1560         717 :                                         ZVAL_UNDEF(src);
    1561         717 :                                         src--;
    1562         717 :                                         dst--;
    1563         717 :                                 } while (src != end);
    1564             :                         }
    1565      466753 :                 } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1566             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1567      466736 :                         EX(opline) += num_args;
    1568             :                 }
    1569             : 
    1570             :                 /* Initialize CV variables (skip arguments) */
    1571      467530 :                 if (EXPECTED(num_args < op_array->last_var)) {
    1572      229749 :                         zval *var = EX_VAR_NUM(num_args);
    1573      229749 :                         zval *end = EX_VAR_NUM(op_array->last_var);
    1574             : 
    1575             :                         do {
    1576      662765 :                                 ZVAL_UNDEF(var);
    1577      662765 :                                 var++;
    1578      662765 :                         } while (var != end);
    1579             :                 }
    1580             : 
    1581      467530 :                 if (op_array->this_var != -1 && EX(object)) {
    1582       17466 :                         ZVAL_OBJ(EX_VAR(op_array->this_var), EX(object));
    1583       17466 :                         GC_REFCOUNT(EX(object))++;
    1584             :                 }
    1585             :         }
    1586             : 
    1587      487747 :         if (!op_array->run_time_cache && op_array->last_cache_slot) {
    1588       19245 :                 if (op_array->function_name) {
    1589        3372 :                         op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
    1590             :                 } else {
    1591       17559 :                         op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
    1592             :                 }
    1593             :         }
    1594      487747 :         EX(run_time_cache) = op_array->run_time_cache;
    1595             : 
    1596      487747 :         EG(current_execute_data) = execute_data;
    1597             : }
    1598             : /* }}} */
    1599             : 
    1600          82 : ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data *call, zend_op_array *op_array, zval *return_value TSRMLS_DC) /* {{{ */
    1601             : {
    1602             :         /*
    1603             :          * Normally the execute_data is allocated on the VM stack (because it does
    1604             :          * not actually do any allocation and thus is faster). For generators
    1605             :          * though this behavior would be suboptimal, because the (rather large)
    1606             :          * structure would have to be copied back and forth every time execution is
    1607             :          * suspended or resumed. That's why for generators the execution context
    1608             :          * is allocated using a separate VM stack, thus allowing to save and
    1609             :          * restore it simply by replacing a pointer.
    1610             :          */
    1611             :         zend_execute_data *execute_data;
    1612          82 :         uint32_t num_args = call->num_args;
    1613             : 
    1614         164 :         EG(argument_stack) = zend_vm_stack_new_page(
    1615          82 :                 MAX(ZEND_VM_STACK_PAGE_SIZE, 
    1616             :                         ZEND_CALL_FRAME_SLOT + MAX(op_array->last_var + op_array->T, num_args)));
    1617          82 :         EG(argument_stack)->prev = NULL;
    1618             : 
    1619         246 :         execute_data = zend_vm_stack_push_call_frame(
    1620             :                 (zend_function*)op_array,
    1621             :                 num_args,
    1622          82 :                 call->flags,
    1623             :                 call->called_scope,
    1624             :                 call->object,
    1625             :                 NULL TSRMLS_CC);
    1626          82 :         EX(num_args) = num_args;
    1627             : 
    1628             :         /* copy arguments */
    1629          82 :         if (num_args > 0) {
    1630          25 :                 zval *arg_src = ZEND_CALL_ARG(call, 1);
    1631          25 :                 zval *arg_dst = ZEND_CALL_ARG(execute_data, 1);
    1632             :                 uint32_t i;
    1633             : 
    1634          59 :                 for (i = 0; i < num_args; i++) {
    1635          34 :                         ZVAL_COPY_VALUE(arg_dst + i, arg_src + i);
    1636             :                 }
    1637             :         }
    1638             : 
    1639          82 :         EX(symbol_table) = NULL;
    1640             : 
    1641             :         i_init_func_execute_data(execute_data, op_array, return_value, VM_FRAME_TOP_FUNCTION TSRMLS_CC);
    1642             : 
    1643          82 :         return execute_data;
    1644             : }
    1645             : /* }}} */
    1646             : 
    1647      467530 : ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, vm_frame_kind frame_kind TSRMLS_DC) /* {{{ */
    1648             : {
    1649      467530 :         EX(prev_execute_data) = EG(current_execute_data);
    1650             :         i_init_execute_data(execute_data, op_array, return_value, frame_kind TSRMLS_CC);
    1651      467530 : }
    1652             : /* }}} */
    1653             : 
    1654             : static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(const zend_op *opline, zend_execute_data *call TSRMLS_DC) /* {{{ */
    1655             : {
    1656        3443 :         uint32_t arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK;
    1657        6886 :         return ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num);
    1658             : }
    1659             : /* }}} */
    1660             : 
    1661           3 : static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, uint32_t passed_args, uint32_t additional_args TSRMLS_DC) /* {{{ */
    1662             : {
    1663             :         zend_execute_data *new_call;
    1664           3 :         int used_stack = (EG(argument_stack)->top - (zval*)call) + additional_args;
    1665             :                 
    1666             :         /* copy call frame into new stack segment */
    1667           3 :         zend_vm_stack_extend(used_stack TSRMLS_CC);
    1668           3 :         new_call = (zend_execute_data*)EG(argument_stack)->top;
    1669           3 :         EG(argument_stack)->top += used_stack;               
    1670           3 :         *new_call = *call;
    1671           3 :         if (passed_args) {
    1672           1 :                 zval *src = ZEND_CALL_ARG(call, 1);
    1673           1 :                 zval *dst = ZEND_CALL_ARG(new_call, 1);
    1674             :                 do {
    1675       10000 :                         ZVAL_COPY_VALUE(dst, src);
    1676       10000 :                         passed_args--;
    1677       10000 :                         src++;
    1678       10000 :                         dst++;
    1679       10000 :                 } while (passed_args);
    1680             :         }
    1681             : 
    1682             :         /* delete old call_frame from previous stack segment */
    1683           3 :         EG(argument_stack)->prev->top = (zval*)call;
    1684             : 
    1685             :         /* delete previous stack segment if it becames empty */
    1686           3 :         if (UNEXPECTED(EG(argument_stack)->prev->top == ZEND_VM_STACK_ELEMETS(EG(argument_stack)->prev))) {
    1687           0 :                 zend_vm_stack r = EG(argument_stack)->prev;
    1688             : 
    1689           0 :                 EG(argument_stack)->prev = r->prev;
    1690           0 :                 efree(r);
    1691             :         }
    1692             : 
    1693           3 :         return new_call;
    1694             : }
    1695             : /* }}} */
    1696             : 
    1697             : static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data **call, uint32_t passed_args, uint32_t additional_args TSRMLS_DC) /* {{{ */
    1698             : {
    1699         204 :         if (EXPECTED(EG(argument_stack)->end - EG(argument_stack)->top > additional_args)) {
    1700         201 :                 EG(argument_stack)->top += additional_args;
    1701             :         } else {
    1702           3 :                 *call = zend_vm_stack_copy_call_frame(*call, passed_args, additional_args TSRMLS_CC);
    1703             :         }
    1704             : }
    1705             : /* }}} */
    1706             : 
    1707             : #define ZEND_VM_NEXT_OPCODE() \
    1708             :         CHECK_SYMBOL_TABLES() \
    1709             :         ZEND_VM_INC_OPCODE(); \
    1710             :         ZEND_VM_CONTINUE()
    1711             : 
    1712             : #define ZEND_VM_SET_OPCODE(new_op) \
    1713             :         CHECK_SYMBOL_TABLES() \
    1714             :         OPLINE = new_op
    1715             : 
    1716             : #define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
    1717             :         CHECK_SYMBOL_TABLES() \
    1718             :         OPLINE = ((zend_op*)(((char*)opline)+(offset)))
    1719             : 
    1720             : #define ZEND_VM_JMP(new_op) \
    1721             :         if (EXPECTED(!EG(exception))) { \
    1722             :                 ZEND_VM_SET_OPCODE(new_op); \
    1723             :         } else { \
    1724             :                 LOAD_OPLINE(); \
    1725             :         } \
    1726             :         ZEND_VM_CONTINUE()
    1727             : 
    1728             : #define ZEND_VM_INC_OPCODE() \
    1729             :         OPLINE++
    1730             : 
    1731             : #ifdef __GNUC__
    1732             : # define ZEND_VM_GUARD(name) __asm__("#" #name)
    1733             : #else
    1734             : # define ZEND_VM_GUARD(name)
    1735             : #endif
    1736             : 
    1737             : #include "zend_vm_execute.h"
    1738             : 
    1739           0 : ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
    1740             : {
    1741           0 :         if (opcode != ZEND_USER_OPCODE) {
    1742           0 :                 if (handler == NULL) {
    1743             :                         /* restore the original handler */
    1744           0 :                         zend_user_opcodes[opcode] = opcode;
    1745             :                 } else {
    1746           0 :                         zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
    1747             :                 }
    1748           0 :                 zend_user_opcode_handlers[opcode] = handler;
    1749           0 :                 return SUCCESS;
    1750             :         }
    1751           0 :         return FAILURE;
    1752             : }
    1753             : 
    1754           0 : ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
    1755             : {
    1756           0 :         return zend_user_opcode_handlers[opcode];
    1757             : }
    1758             : 
    1759           0 : ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) {
    1760           0 :         return get_zval_ptr(op_type, node, execute_data, should_free, type);
    1761             : }
    1762             : 
    1763             : /*
    1764             :  * Local variables:
    1765             :  * tab-width: 4
    1766             :  * c-basic-offset: 4
    1767             :  * indent-tabs-mode: t
    1768             :  * End:
    1769             :  */

Generated by: LCOV version 1.10

Generated at Sat, 27 Sep 2014 16:43:05 +0000 (3 days ago)

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