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: 1035 1199 86.3 %
Date: 2016-09-27 Functions: 52 64 81.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2016 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             :    |          Dmitry Stogov <dmitry@zend.com>                             |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : /* $Id$ */
      22             : 
      23             : #define ZEND_INTENSIVE_DEBUGGING 0
      24             : 
      25             : #include <stdio.h>
      26             : #include <signal.h>
      27             : 
      28             : #include "zend.h"
      29             : #include "zend_compile.h"
      30             : #include "zend_execute.h"
      31             : #include "zend_API.h"
      32             : #include "zend_ptr_stack.h"
      33             : #include "zend_constants.h"
      34             : #include "zend_extensions.h"
      35             : #include "zend_ini.h"
      36             : #include "zend_exceptions.h"
      37             : #include "zend_interfaces.h"
      38             : #include "zend_closures.h"
      39             : #include "zend_generators.h"
      40             : #include "zend_vm.h"
      41             : #include "zend_dtrace.h"
      42             : #include "zend_inheritance.h"
      43             : #include "zend_type_info.h"
      44             : 
      45             : /* Virtual current working directory support */
      46             : #include "zend_virtual_cwd.h"
      47             : 
      48             : #define _CONST_CODE  0
      49             : #define _TMP_CODE    1
      50             : #define _VAR_CODE    2
      51             : #define _UNUSED_CODE 3
      52             : #define _CV_CODE     4
      53             : 
      54             : typedef int (ZEND_FASTCALL *incdec_t)(zval *);
      55             : 
      56             : #define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type)
      57             : #define get_zval_ptr_deref(op_type, node, ex, should_free, type) _get_zval_ptr_deref(op_type, node, ex, should_free, type)
      58             : #define get_zval_ptr_r(op_type, node, ex, should_free) _get_zval_ptr_r(op_type, node, ex, should_free)
      59             : #define get_zval_ptr_r_deref(op_type, node, ex, should_free) _get_zval_ptr_r_deref(op_type, node, ex, should_free)
      60             : #define get_zval_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_undef(op_type, node, ex, should_free, type)
      61             : #define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
      62             : #define get_zval_ptr_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
      63             : #define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type)
      64             : #define get_obj_zval_ptr_undef(op_type, node, ex, should_free, type) _get_obj_zval_ptr_undef(op_type, node, ex, should_free, type)
      65             : #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)
      66             : 
      67             : /* Prototypes */
      68             : static void zend_extension_statement_handler(const zend_extension *extension, zend_execute_data *frame);
      69             : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_execute_data *frame);
      70             : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_execute_data *frame);
      71             : 
      72             : #define RETURN_VALUE_USED(opline) ((opline)->result_type != IS_UNUSED)
      73             : 
      74          86 : static ZEND_FUNCTION(pass)
      75             : {
      76          86 : }
      77             : 
      78             : ZEND_API const zend_internal_function zend_pass_function = {
      79             :         ZEND_INTERNAL_FUNCTION, /* type              */
      80             :         {0, 0, 0},              /* arg_flags         */
      81             :         0,                      /* fn_flags          */
      82             :         NULL,                   /* name              */
      83             :         NULL,                   /* scope             */
      84             :         NULL,                   /* prototype         */
      85             :         0,                      /* num_args          */
      86             :         0,                      /* required_num_args */
      87             :         NULL,                   /* arg_info          */
      88             :         ZEND_FN(pass),          /* handler           */
      89             :         NULL,                   /* module            */
      90             :         {NULL,NULL,NULL,NULL}   /* reserved          */
      91             : };
      92             : 
      93             : #undef zval_ptr_dtor
      94             : #define zval_ptr_dtor(zv) i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC)
      95             : 
      96             : #define READY_TO_DESTROY(zv) \
      97             :         (UNEXPECTED(zv) && Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) == 1)
      98             : 
      99             : #define EXTRACT_ZVAL_PTR(zv) do {               \
     100             :         zval *__zv = (zv);                                                              \
     101             :         if (EXPECTED(Z_TYPE_P(__zv) == IS_INDIRECT)) {  \
     102             :                 ZVAL_COPY(__zv, Z_INDIRECT_P(__zv));        \
     103             :         }                                                                                               \
     104             : } while (0)
     105             : 
     106             : #define FREE_OP(should_free) \
     107             :         if (should_free) { \
     108             :                 zval_ptr_dtor_nogc(should_free); \
     109             :         }
     110             : 
     111             : #define FREE_UNFETCHED_OP(type, var) \
     112             :         if ((type) & (IS_TMP_VAR|IS_VAR)) { \
     113             :                 zval_ptr_dtor_nogc(EX_VAR(var)); \
     114             :         }
     115             : 
     116             : #define FREE_OP_VAR_PTR(should_free) \
     117             :         if (should_free) { \
     118             :                 zval_ptr_dtor_nogc(should_free); \
     119             :         }
     120             : 
     121             : #define CV_DEF_OF(i) (EX(func)->op_array.vars[i])
     122             : 
     123             : #define ZEND_VM_MAIN_STACK_PAGE_SLOTS (16 * 1024) /* should be a power of 2 */
     124             : #define ZEND_VM_GENERATOR_STACK_PAGE_SLOTS (256)
     125             : 
     126             : #define ZEND_VM_STACK_PAGE_SLOTS(gen) ((gen) ? ZEND_VM_GENERATOR_STACK_PAGE_SLOTS : ZEND_VM_MAIN_STACK_PAGE_SLOTS)
     127             : 
     128             : #define ZEND_VM_STACK_PAGE_SIZE(gen)  (ZEND_VM_STACK_PAGE_SLOTS(gen) * sizeof(zval))
     129             : 
     130             : #define ZEND_VM_STACK_FREE_PAGE_SIZE(gen) \
     131             :         ((ZEND_VM_STACK_PAGE_SLOTS(gen) - ZEND_VM_STACK_HEADER_SLOTS) * sizeof(zval))
     132             : 
     133             : #define ZEND_VM_STACK_PAGE_ALIGNED_SIZE(gen, size) \
     134             :         (((size) + ZEND_VM_STACK_HEADER_SLOTS * sizeof(zval) \
     135             :           + (ZEND_VM_STACK_PAGE_SIZE(gen) - 1)) & ~(ZEND_VM_STACK_PAGE_SIZE(gen) - 1))
     136             : 
     137             : static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend_vm_stack prev) {
     138       24000 :         zend_vm_stack page = (zend_vm_stack)emalloc(size);
     139             : 
     140       24000 :         page->top = ZEND_VM_STACK_ELEMENTS(page);
     141       24000 :         page->end = (zval*)((char*)page + size);
     142       24000 :         page->prev = prev;
     143       24000 :         return page;
     144             : }
     145             : 
     146       23904 : ZEND_API void zend_vm_stack_init(void)
     147             : {
     148       23904 :         EG(vm_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE(0 /* main stack */), NULL);
     149       23904 :         EG(vm_stack)->top++;
     150       23904 :         EG(vm_stack_top) = EG(vm_stack)->top;
     151       23904 :         EG(vm_stack_end) = EG(vm_stack)->end;
     152       23904 : }
     153             : 
     154       23925 : ZEND_API void zend_vm_stack_destroy(void)
     155             : {
     156       23925 :         zend_vm_stack stack = EG(vm_stack);
     157             : 
     158       71775 :         while (stack != NULL) {
     159       23925 :                 zend_vm_stack p = stack->prev;
     160       23925 :                 efree(stack);
     161       23925 :                 stack = p;
     162             :         }
     163       23925 : }
     164             : 
     165          96 : ZEND_API void* zend_vm_stack_extend(size_t size)
     166             : {
     167             :         zend_vm_stack stack;
     168             :         void *ptr;
     169             : 
     170          96 :         stack = EG(vm_stack);
     171          96 :         stack->top = EG(vm_stack_top);
     172         204 :         EG(vm_stack) = stack = zend_vm_stack_new_page(
     173          96 :                 EXPECTED(size < ZEND_VM_STACK_FREE_PAGE_SIZE(0)) ?
     174          12 :                         ZEND_VM_STACK_PAGE_SIZE(0) : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(0, size),
     175             :                 stack);
     176          96 :         ptr = stack->top;
     177          96 :         EG(vm_stack_top) = (void*)(((char*)ptr) + size);
     178          96 :         EG(vm_stack_end) = stack->end;
     179          96 :         return ptr;
     180             : }
     181             : 
     182           0 : ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data, uint32_t var)
     183             : {
     184           0 :         return EX_VAR(var);
     185             : }
     186             : 
     187             : static zend_always_inline zval *_get_zval_ptr_tmp(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     188             : {
     189     9522470 :         zval *ret = EX_VAR(var);
     190     9522470 :         *should_free = ret;
     191             : 
     192             :         ZEND_ASSERT(Z_TYPE_P(ret) != IS_REFERENCE);
     193             : 
     194     9522470 :         return ret;
     195             : }
     196             : 
     197             : static zend_always_inline zval *_get_zval_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     198             : {
     199    70565602 :         zval *ret = EX_VAR(var);
     200             : 
     201    70565602 :         *should_free = ret;
     202    70565602 :         return ret;
     203             : }
     204             : 
     205             : static zend_always_inline zval *_get_zval_ptr_var_deref(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     206             : {
     207     1699064 :         zval *ret = EX_VAR(var);
     208             : 
     209     1699064 :         *should_free = ret;
     210     1699064 :         ZVAL_DEREF(ret);
     211     1699064 :         return ret;
     212             : }
     213             : 
     214         555 : static zend_never_inline ZEND_COLD void zval_undefined_cv(uint32_t var, const zend_execute_data *execute_data)
     215             : {
     216         555 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     217             : 
     218         555 :         zend_error(E_NOTICE, "Undefined variable: %s", ZSTR_VAL(cv));
     219         555 : }
     220             : 
     221           0 : static zend_never_inline zval *_get_zval_cv_lookup(zval *ptr, uint32_t var, int type, const zend_execute_data *execute_data)
     222             : {
     223           0 :         switch (type) {
     224             :                 case BP_VAR_R:
     225             :                 case BP_VAR_UNSET:
     226           0 :                         zval_undefined_cv(var, execute_data);
     227             :                         /* break missing intentionally */
     228             :                 case BP_VAR_IS:
     229           0 :                         ptr = &EG(uninitialized_zval);
     230           0 :                         break;
     231             :                 case BP_VAR_RW:
     232           0 :                         zval_undefined_cv(var, execute_data);
     233             :                         /* break missing intentionally */
     234             :                 case BP_VAR_W:
     235           0 :                         ZVAL_NULL(ptr);
     236             :                         break;
     237             :         }
     238           0 :         return ptr;
     239             : }
     240             : 
     241             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_R(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     242             : {
     243         529 :         zval_undefined_cv(var, execute_data);
     244         529 :         return &EG(uninitialized_zval);
     245             : }
     246             : 
     247             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_UNSET(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     248             : {
     249           0 :         zval_undefined_cv(var, execute_data);
     250           0 :         return &EG(uninitialized_zval);
     251             : }
     252             : 
     253             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_RW(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     254             : {
     255           6 :         ZVAL_NULL(ptr);
     256           6 :         zval_undefined_cv(var, execute_data);
     257           6 :         return ptr;
     258             : }
     259             : 
     260             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_W(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     261             : {
     262     5748297 :         ZVAL_NULL(ptr);
     263     5748297 :         return ptr;
     264             : }
     265             : 
     266             : static zend_always_inline zval *_get_zval_ptr_cv(const zend_execute_data *execute_data, uint32_t var, int type)
     267             : {
     268         125 :         zval *ret = EX_VAR(var);
     269             : 
     270         125 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     271           0 :                 return _get_zval_cv_lookup(ret, var, type, execute_data);
     272             :         }
     273         125 :         return ret;
     274             : }
     275             : 
     276             : static zend_always_inline zval *_get_zval_ptr_cv_undef(const zend_execute_data *execute_data, uint32_t var)
     277             : {
     278    99611267 :         return EX_VAR(var);
     279             : }
     280             : 
     281             : static zend_always_inline zval *_get_zval_ptr_cv_deref(const zend_execute_data *execute_data, uint32_t var, int type)
     282             : {
     283             :         zval *ret = EX_VAR(var);
     284             : 
     285             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     286             :                 return _get_zval_cv_lookup(ret, var, type, execute_data);
     287             :         }
     288             :         ZVAL_DEREF(ret);
     289             :         return ret;
     290             : }
     291             : 
     292             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, uint32_t var)
     293             : {
     294    10840311 :         zval *ret = EX_VAR(var);
     295             : 
     296    10840311 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     297         191 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data);
     298             :         }
     299    10840120 :         return ret;
     300             : }
     301             : 
     302             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_R(const zend_execute_data *execute_data, uint32_t var)
     303             : {
     304     4210985 :         zval *ret = EX_VAR(var);
     305             : 
     306     4210985 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     307           6 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data);
     308             :         }
     309     4210979 :         ZVAL_DEREF(ret);
     310     4210979 :         return ret;
     311             : }
     312             : 
     313             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var)
     314             : {
     315          92 :         zval *ret = EX_VAR(var);
     316             : 
     317          92 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     318           0 :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data);
     319             :         }
     320          92 :         return ret;
     321             : }
     322             : 
     323             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var)
     324             : {
     325             :         zval *ret = EX_VAR(var);
     326             : 
     327             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     328             :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data);
     329             :         }
     330             :         ZVAL_DEREF(ret);
     331             :         return ret;
     332             : }
     333             : 
     334             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, uint32_t var)
     335             : {
     336         274 :         zval *ret = EX_VAR(var);
     337             : 
     338         274 :         return ret;
     339             : }
     340             : 
     341             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_IS(const zend_execute_data *execute_data, uint32_t var)
     342             : {
     343             :         zval *ret = EX_VAR(var);
     344             : 
     345             :         ZVAL_DEREF(ret);
     346             :         return ret;
     347             : }
     348             : 
     349             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var)
     350             : {
     351     8762692 :         zval *ret = EX_VAR(var);
     352             : 
     353     8762692 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     354           0 :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data);
     355             :         }
     356     8762692 :         return ret;
     357             : }
     358             : 
     359             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var)
     360             : {
     361             :         zval *ret = EX_VAR(var);
     362             : 
     363             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     364             :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data);
     365             :         }
     366             :         ZVAL_DEREF(ret);
     367             :         return ret;
     368             : }
     369             : 
     370             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
     371             : {
     372     9775701 :         zval *ret = EX_VAR(var);
     373             : 
     374     9775701 :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     375     5748297 :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data);
     376             :         }
     377     4027404 :         return ret;
     378             : }
     379             : 
     380             : static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
     381             : {
     382    37710253 :         return EX_VAR(var);
     383             : }
     384             : 
     385             : static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var)
     386             : {
     387    11479251 :         return EX_VAR(var);
     388             : }
     389             : 
     390             : static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var)
     391             : {
     392       24952 :         return EX_VAR(var);
     393             : }
     394             : 
     395             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
     396             : {
     397             :         zval *ret = EX_VAR(var);
     398             : 
     399             :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     400             :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data);
     401             :         }
     402             :         ZVAL_DEREF(ret);
     403             :         return ret;
     404             : }
     405             : 
     406             : static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free, int type)
     407             : {
     408         174 :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     409          42 :                 if (op_type == IS_TMP_VAR) {
     410          50 :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     411             :                 } else {
     412             :                         ZEND_ASSERT(op_type == IS_VAR);
     413          34 :                         return _get_zval_ptr_var(node.var, execute_data, should_free);
     414             :                 }
     415             :         } else {
     416         132 :                 *should_free = NULL;
     417         132 :                 if (op_type == IS_CONST) {
     418           7 :                         return EX_CONSTANT(node);
     419         125 :                 } else if (op_type == IS_CV) {
     420         250 :                         return _get_zval_ptr_cv(execute_data, node.var, type);
     421             :                 } else {
     422           0 :                         return NULL;
     423             :                 }
     424             :         }
     425             : }
     426             : 
     427             : static zend_always_inline zval *_get_zval_ptr_r(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free)
     428             : {
     429     1182476 :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     430        1106 :                 if (op_type == IS_TMP_VAR) {
     431        2208 :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     432             :                 } else {
     433             :                         ZEND_ASSERT(op_type == IS_VAR);
     434           4 :                         return _get_zval_ptr_var(node.var, execute_data, should_free);
     435             :                 }
     436             :         } else {
     437     1181370 :                 *should_free = NULL;
     438     1181370 :                 if (op_type == IS_CONST) {
     439          64 :                         return EX_CONSTANT(node);
     440     1181306 :                 } else if (op_type == IS_CV) {
     441     2362612 :                         return _get_zval_ptr_cv_BP_VAR_R(execute_data, node.var);
     442             :                 } else {
     443           0 :                         return NULL;
     444             :                 }
     445             :         }
     446             : }
     447             : 
     448             : static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free, int type)
     449             : {
     450             :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     451             :                 if (op_type == IS_TMP_VAR) {
     452             :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     453             :                 } else {
     454             :                         ZEND_ASSERT(op_type == IS_VAR);
     455             :                         return _get_zval_ptr_var_deref(node.var, execute_data, should_free);
     456             :                 }
     457             :         } else {
     458             :                 *should_free = NULL;
     459             :                 if (op_type == IS_CONST) {
     460             :                         return EX_CONSTANT(node);
     461             :                 } else if (op_type == IS_CV) {
     462             :                         return _get_zval_ptr_cv_deref(execute_data, node.var, type);
     463             :                 } else {
     464             :                         return NULL;
     465             :                 }
     466             :         }
     467             : }
     468             : 
     469             : static zend_always_inline zval *_get_zval_ptr_r_deref(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free)
     470             : {
     471             :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     472             :                 if (op_type == IS_TMP_VAR) {
     473             :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     474             :                 } else {
     475             :                         ZEND_ASSERT(op_type == IS_VAR);
     476             :                         return _get_zval_ptr_var_deref(node.var, execute_data, should_free);
     477             :                 }
     478             :         } else {
     479             :                 *should_free = NULL;
     480             :                 if (op_type == IS_CONST) {
     481             :                         return EX_CONSTANT(node);
     482             :                 } else if (op_type == IS_CV) {
     483             :                         return _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, node.var);
     484             :                 } else {
     485             :                         return NULL;
     486             :                 }
     487             :         }
     488             : }
     489             : 
     490             : static zend_always_inline zval *_get_zval_ptr_undef(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free, int type)
     491             : {
     492          70 :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     493          17 :                 if (op_type == IS_TMP_VAR) {
     494           0 :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     495             :                 } else {
     496             :                         ZEND_ASSERT(op_type == IS_VAR);
     497          34 :                         return _get_zval_ptr_var(node.var, execute_data, should_free);
     498             :                 }
     499             :         } else {
     500          53 :                 *should_free = NULL;
     501          53 :                 if (op_type == IS_CONST) {
     502          34 :                         return EX_CONSTANT(node);
     503          19 :                 } else if (op_type == IS_CV) {
     504          38 :                         return _get_zval_ptr_cv_undef(execute_data, node.var);
     505             :                 } else {
     506           0 :                         return NULL;
     507             :                 }
     508             :         }
     509             : }
     510             : 
     511             : static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     512             : {
     513     1157895 :         zval *ret = EX_VAR(var);
     514             : 
     515     1157895 :         if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
     516      970986 :                 *should_free = NULL;
     517      970986 :                 ret = Z_INDIRECT_P(ret);
     518             :         } else {
     519      186909 :                 *should_free = ret;
     520             :         }
     521     1157895 :         return ret;
     522             : }
     523             : 
     524             : static inline zval *_get_zval_ptr_ptr(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free, int type)
     525             : {
     526             :         if (op_type == IS_CV) {
     527             :                 *should_free = NULL;
     528             :                 return _get_zval_ptr_cv(execute_data, node.var, type);
     529             :         } else /* if (op_type == IS_VAR) */ {
     530             :                 ZEND_ASSERT(op_type == IS_VAR);
     531             :                 return _get_zval_ptr_ptr_var(node.var, execute_data, should_free);
     532             :         }
     533             : }
     534             : 
     535             : static zend_always_inline zval *_get_obj_zval_ptr_unused(zend_execute_data *execute_data)
     536             : {       
     537      420428 :         return &EX(This);
     538             : }
     539             : 
     540             : static inline zval *_get_obj_zval_ptr(int op_type, znode_op op, zend_execute_data *execute_data, zend_free_op *should_free, int type)
     541             : {
     542             :         if (op_type == IS_UNUSED) {
     543             :                 *should_free = NULL;
     544             :                 return &EX(This);
     545             :         }
     546             :         return get_zval_ptr(op_type, op, execute_data, should_free, type);
     547             : }
     548             : 
     549             : static inline zval *_get_obj_zval_ptr_undef(int op_type, znode_op op, zend_execute_data *execute_data, zend_free_op *should_free, int type)
     550             : {
     551             :         if (op_type == IS_UNUSED) {
     552             :                 *should_free = NULL;
     553             :                 return &EX(This);
     554             :         }
     555             :         return get_zval_ptr_undef(op_type, op, execute_data, should_free, type);
     556             : }
     557             : 
     558             : static inline zval *_get_obj_zval_ptr_ptr(int op_type, znode_op node, zend_execute_data *execute_data, zend_free_op *should_free, int type)
     559             : {
     560             :         if (op_type == IS_UNUSED) {
     561             :                 *should_free = NULL;
     562             :                 return &EX(This);
     563             :         }
     564             :         return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type);
     565             : }
     566             : 
     567      282999 : static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr)
     568             : {
     569             :         zend_reference *ref;
     570             :         zval garbage;
     571             : 
     572      282999 :         if (EXPECTED(!Z_ISREF_P(value_ptr))) {
     573       63573 :                 ZVAL_NEW_REF(value_ptr, value_ptr);
     574      219426 :         } else if (UNEXPECTED(variable_ptr == value_ptr)) {
     575           1 :                 return;
     576             :         }
     577             : 
     578      282998 :         ref = Z_REF_P(value_ptr);
     579      282998 :         GC_REFCOUNT(ref)++;
     580      282998 :         ZVAL_COPY_VALUE(&garbage, variable_ptr);
     581      282998 :         ZVAL_REF(variable_ptr, ref);
     582             :         zval_ptr_dtor(&garbage);
     583             : }
     584             : 
     585             : /* this should modify object only if it's empty */
     586          27 : static inline int make_real_object(zval *object)
     587             : {
     588          27 :         if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     589          20 :                 if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE)) {
     590             :                         /* nothing to destroy */
     591          13 :                 } else if (EXPECTED((Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
     592             :                         zval_ptr_dtor_nogc(object);
     593             :                 } else {
     594           9 :                         return 0;
     595             :                 }
     596          11 :                 object_init(object);
     597          11 :                 zend_error(E_WARNING, "Creating default object from empty value");
     598             :         }
     599          18 :         return 1;
     600             : }
     601             : 
     602        1278 : static zend_class_entry *zend_verify_internal_arg_class_kind(
     603             :                 const zend_internal_arg_info *cur_arg_info)
     604             : {
     605             :         zend_string *key;
     606             :         zend_class_entry *ce;
     607             :         ALLOCA_FLAG(use_heap);
     608             : 
     609        2556 :         ZSTR_ALLOCA_INIT(key, cur_arg_info->class_name, strlen(cur_arg_info->class_name), use_heap);
     610        1278 :         ce = zend_fetch_class(key, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
     611        1278 :         ZSTR_ALLOCA_FREE(key, use_heap);
     612             : 
     613        1278 :         return ce;
     614             : }
     615             : 
     616             : static zend_always_inline zend_class_entry* zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info)
     617             : {
     618         134 :         return zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
     619             : }
     620             : 
     621         410 : static ZEND_COLD void zend_verify_type_error_common(
     622             :                 const zend_function *zf, const zend_arg_info *arg_info,
     623             :                 const zend_class_entry *ce, zval *value,
     624             :                 const char **fname, const char **fsep, const char **fclass,
     625             :                 const char **need_msg, const char **need_kind, const char **need_or_null,
     626             :                 const char **given_msg, const char **given_kind)
     627             : {
     628         410 :         zend_bool is_interface = 0;
     629         410 :         *fname = ZSTR_VAL(zf->common.function_name);
     630             : 
     631         410 :         if (zf->common.scope) {
     632          29 :                 *fsep =  "::";
     633          29 :                 *fclass = ZSTR_VAL(zf->common.scope->name);
     634             :         } else {
     635         381 :                 *fsep =  "";
     636         381 :                 *fclass = "";
     637             :         }
     638             : 
     639         410 :         switch (arg_info->type_hint) {
     640             :                 case IS_OBJECT:
     641         230 :                         if (ce) {
     642         220 :                                 if (ce->ce_flags & ZEND_ACC_INTERFACE) {
     643          45 :                                         *need_msg = "implement interface ";
     644          45 :                                         is_interface = 1;
     645             :                                 } else {
     646         175 :                                         *need_msg = "be an instance of ";
     647             :                                 }
     648         220 :                                 *need_kind = ZSTR_VAL(ce->name);
     649             :                         } else {
     650             :                                 /* We don't know whether it's a class or interface, assume it's a class */
     651          10 :                                 *need_msg = "be an instance of ";
     652          20 :                                 *need_kind = zf->common.type == ZEND_INTERNAL_FUNCTION
     653           0 :                                         ? ((zend_internal_arg_info *) arg_info)->class_name
     654          10 :                                         : ZSTR_VAL(arg_info->class_name);
     655             :                         }
     656         230 :                         break;
     657             :                 case IS_CALLABLE:
     658           5 :                         *need_msg = "be callable";
     659           5 :                         *need_kind = "";
     660           5 :                         break;
     661             :                 case IS_ITERABLE:
     662           5 :                         *need_msg = "be iterable";
     663           5 :                         *need_kind = "";
     664           5 :                         break;
     665             :                 default:
     666         170 :                         *need_msg = "be of the type ";
     667         170 :                         *need_kind = zend_get_type_by_const(arg_info->type_hint);
     668             :                         break;
     669             :         }
     670             : 
     671         410 :         if (arg_info->allow_null) {
     672          31 :                 *need_or_null = is_interface ? " or be null" : " or null";
     673             :         } else {
     674         379 :                 *need_or_null = "";
     675             :         }
     676             : 
     677         410 :         if (value) {
     678         723 :                 if (arg_info->type_hint == IS_OBJECT && Z_TYPE_P(value) == IS_OBJECT) {
     679          93 :                         *given_msg = "instance of ";
     680          93 :                         *given_kind = ZSTR_VAL(Z_OBJCE_P(value)->name);
     681             :                 } else {
     682         310 :                         *given_msg = zend_zval_type_name(value);
     683         310 :                         *given_kind = "";
     684             :                 }
     685             :         } else {
     686           7 :                 *given_msg = "none";
     687           7 :                 *given_kind = "";
     688             :         }
     689         410 : }
     690             : 
     691         354 : static ZEND_COLD void zend_verify_arg_error(
     692             :                 const zend_function *zf, const zend_arg_info *arg_info,
     693             :                 int arg_num, const zend_class_entry *ce, zval *value)
     694             : {
     695         354 :         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
     696             :         const char *fname, *fsep, *fclass;
     697             :         const char *need_msg, *need_kind, *need_or_null, *given_msg, *given_kind;
     698             : 
     699         354 :         if (value) {
     700         354 :                 zend_verify_type_error_common(
     701             :                         zf, arg_info, ce, value,
     702             :                         &fname, &fsep, &fclass, &need_msg, &need_kind, &need_or_null, &given_msg, &given_kind);
     703             : 
     704         354 :                 if (zf->common.type == ZEND_USER_FUNCTION) {
     705         315 :                         if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     706         312 :                                 zend_type_error("Argument %d passed to %s%s%s() must %s%s%s, %s%s given, called in %s on line %d",
     707             :                                                 arg_num, fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind,
     708         312 :                                                 ZSTR_VAL(ptr->func->op_array.filename), ptr->opline->lineno);
     709             :                         } else {
     710           3 :                                 zend_type_error("Argument %d passed to %s%s%s() must %s%s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind);
     711             :                         }
     712             :                 } else {
     713         195 :                         zend_type_error("Argument %d passed to %s%s%s() must %s%s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind);
     714             :                 }
     715             :         } else {
     716           0 :                 zend_missing_arg_error(ptr);
     717             :         }
     718         354 : }
     719             : 
     720           5 : static int is_null_constant(zend_class_entry *scope, zval *default_value)
     721             : {
     722           5 :         if (Z_CONSTANT_P(default_value)) {
     723             :                 zval constant;
     724             : 
     725           5 :                 ZVAL_COPY(&constant, default_value);
     726           5 :                 if (UNEXPECTED(zval_update_constant_ex(&constant, scope) != SUCCESS)) {
     727           0 :                         return 0;
     728             :                 }
     729           5 :                 if (Z_TYPE(constant) == IS_NULL) {
     730           4 :                         return 1;
     731             :                 }
     732             :                 zval_ptr_dtor(&constant);
     733             :         }
     734           1 :         return 0;
     735             : }
     736             : 
     737         142 : static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *arg)
     738             : {
     739         142 :         switch (type_hint) {
     740             :                 case _IS_BOOL: {
     741             :                         zend_bool dest;
     742             : 
     743          27 :                         if (!zend_parse_arg_bool_weak(arg, &dest)) {
     744           8 :                                 return 0;
     745             :                         }
     746             :                         zval_ptr_dtor(arg);
     747          19 :                         ZVAL_BOOL(arg, dest);
     748          19 :                         return 1;
     749             :                 }
     750             :                 case IS_LONG: {
     751             :                         zend_long dest;
     752             : 
     753          39 :                         if (!zend_parse_arg_long_weak(arg, &dest)) {
     754          18 :                                 return 0;
     755             :                         }
     756             :                         zval_ptr_dtor(arg);
     757          21 :                         ZVAL_LONG(arg, dest);
     758          21 :                         return 1;
     759             :                 }
     760             :                 case IS_DOUBLE: {
     761             :                         double dest;
     762             : 
     763          30 :                         if (!zend_parse_arg_double_weak(arg, &dest)) {
     764          12 :                                 return 0;
     765             :                         }
     766             :                         zval_ptr_dtor(arg);
     767          18 :                         ZVAL_DOUBLE(arg, dest);
     768          18 :                         return 1;
     769             :                 }
     770             :                 case IS_STRING: {
     771             :                         zend_string *dest;
     772             : 
     773             :                         /* on success "arg" is converted to IS_STRING */
     774          28 :                         if (!zend_parse_arg_str_weak(arg, &dest)) {
     775           6 :                                 return 0;
     776             :                         }
     777          22 :                         return 1;
     778             :                 }
     779             :                 default:
     780          18 :                         return 0;
     781             :         }
     782             : }
     783             : 
     784         248 : static zend_bool zend_verify_scalar_type_hint(zend_uchar type_hint, zval *arg, zend_bool strict)
     785             : {
     786         248 :         if (UNEXPECTED(strict)) {
     787             :                 /* SSTH Exception: IS_LONG may be accepted as IS_DOUBLE (converted) */
     788         113 :                 if (type_hint != IS_DOUBLE || Z_TYPE_P(arg) != IS_LONG) {
     789          87 :                         return 0;
     790             :                 }
     791         157 :         } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL)) {
     792             :                 /* NULL may be accepted only by nullable hints (this is already checked) */
     793          19 :                 return 0;
     794             :         }
     795         142 :         return zend_verify_weak_scalar_type_hint(type_hint, arg);
     796             : }
     797             : 
     798             : static zend_always_inline zend_bool zend_check_internal_type(
     799             :                 const zend_function *zf, const zend_internal_arg_info *arg_info,
     800             :                 zval *arg, zend_class_entry **ce, zend_bool is_return_type)
     801             : {
     802        2317 :         if (!arg_info->type_hint) {
     803         710 :                 return 1;
     804             :         }
     805             : 
     806        1607 :         ZVAL_DEREF(arg);
     807        3214 :         if (EXPECTED(arg_info->type_hint == Z_TYPE_P(arg))) {
     808        1466 :                 if (arg_info->class_name) {
     809        1160 :                         *ce = zend_verify_internal_arg_class_kind(arg_info);
     810        1160 :                         return *ce && instanceof_function(Z_OBJCE_P(arg), *ce);
     811             :                 }
     812         306 :                 return 1;
     813             :         }
     814             : 
     815         141 :         if (Z_TYPE_P(arg) == IS_NULL && arg_info->allow_null) {
     816          16 :                 return 1;
     817             :         }
     818             : 
     819         125 :         if (arg_info->class_name) {
     820         118 :                 *ce = zend_verify_internal_arg_class_kind(arg_info);
     821         118 :                 return 0;
     822           7 :         } else if (arg_info->type_hint == IS_CALLABLE) {
     823           0 :                 return zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL);
     824           7 :         } else if (arg_info->type_hint == IS_ITERABLE) {
     825           0 :                 return zend_is_iterable(arg);
     826           7 :         } else if (arg_info->type_hint == _IS_BOOL &&
     827             :                            EXPECTED(Z_TYPE_P(arg) == IS_FALSE || Z_TYPE_P(arg) == IS_TRUE)) {
     828           0 :                 return 1;
     829           7 :         } else if (is_return_type) {
     830             :                 /* Internal return types are always strict */
     831           0 :                 return 0;
     832             :         } else {
     833             :                 /* Internal parameter types honor strict_types */
     834           7 :                 return zend_verify_scalar_type_hint(arg_info->type_hint, arg, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)));
     835             :         }
     836             : }
     837             : 
     838        2349 : static int zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, zval *arg)
     839             : {
     840             :         const zend_internal_arg_info *cur_arg_info;
     841        2349 :         zend_class_entry *ce = NULL;
     842             : 
     843        2349 :         if (EXPECTED(arg_num <= zf->internal_function.num_args)) {
     844        2317 :                 cur_arg_info = &zf->internal_function.arg_info[arg_num-1];
     845          32 :         } else if (zf->internal_function.fn_flags & ZEND_ACC_VARIADIC) {
     846           0 :                 cur_arg_info = &zf->internal_function.arg_info[zf->internal_function.num_args];
     847             :         } else {
     848          32 :                 return 1;
     849             :         }
     850             : 
     851        2317 :         if (UNEXPECTED(!zend_check_internal_type(zf, cur_arg_info, arg, &ce, 0))) {
     852         195 :                 zend_verify_arg_error(zf, (const zend_arg_info *) cur_arg_info, arg_num, ce, arg);
     853         195 :                 return 0;
     854             :         }
     855             : 
     856        2122 :         return 1;
     857             : }
     858             : 
     859        1524 : static zend_never_inline int zend_verify_internal_arg_types(zend_function *fbc, zend_execute_data *call)
     860             : {
     861             :         uint32_t i;
     862        1524 :         uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
     863        1524 :         zval *p = ZEND_CALL_ARG(call, 1);
     864             : 
     865        3678 :         for (i = 0; i < num_args; ++i) {
     866        2349 :                 if (UNEXPECTED(!zend_verify_internal_arg_type(fbc, i + 1, p))) {
     867         195 :                         EG(current_execute_data) = call->prev_execute_data;
     868             :                         zend_vm_stack_free_args(call);
     869         195 :                         return 0;
     870             :                 }
     871        2154 :                 p++;
     872             :         }
     873        1329 :         return 1;
     874             : }
     875             : 
     876             : static zend_always_inline zend_bool zend_check_type(
     877             :                 const zend_function *zf, const zend_arg_info *arg_info,
     878             :                 zval *arg, zend_class_entry **ce, void **cache_slot,
     879             :                 zval *default_value, zend_bool is_return_type)
     880             : {
     881       88829 :         if (!arg_info->type_hint) {
     882         238 :                 return 1;
     883             :         }
     884             : 
     885       88591 :         ZVAL_DEREF(arg);
     886      177182 :         if (EXPECTED(arg_info->type_hint == Z_TYPE_P(arg))) {
     887       88235 :                 if (arg_info->class_name) {
     888       87960 :                         if (EXPECTED(*cache_slot)) {
     889       87842 :                                 *ce = (zend_class_entry *) *cache_slot;
     890             :                         } else {
     891         118 :                                 *ce = zend_verify_arg_class_kind(arg_info);
     892         118 :                                 if (UNEXPECTED(!*ce)) {
     893           6 :                                         return 0;
     894             :                                 }
     895         112 :                                 *cache_slot = (void *) *ce;
     896             :                         }
     897       87954 :                         if (UNEXPECTED(!instanceof_function(Z_OBJCE_P(arg), *ce))) {
     898          17 :                                 return 0;
     899             :                         }
     900             :                 }
     901       88212 :                 return 1;
     902             :         }
     903             : 
     904         356 :         if (Z_TYPE_P(arg) == IS_NULL && (arg_info->allow_null || (default_value && is_null_constant(zf->common.scope, default_value)))) {
     905             :                 /* Null passed to nullable type */
     906          64 :                 return 1;
     907             :         }
     908             : 
     909         292 :         if (UNEXPECTED(arg_info->class_name)) {
     910             :                 /* This is always an error - we fetch the class name for the error message here */
     911          16 :                 if (EXPECTED(*cache_slot)) {
     912           3 :                         *ce = (zend_class_entry *) *cache_slot;
     913             :                 } else {
     914          13 :                         *ce = zend_verify_arg_class_kind(arg_info);
     915          13 :                         if (*ce) {
     916          10 :                                 *cache_slot = (void *) *ce;
     917             :                         }
     918             :                 }
     919          16 :                 return 0;
     920         276 :         } else if (arg_info->type_hint == IS_CALLABLE) {
     921          16 :                 return zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL);
     922         260 :         } else if (arg_info->type_hint == IS_ITERABLE) {
     923           9 :                 return zend_is_iterable(arg);
     924         368 :         } else if (arg_info->type_hint == _IS_BOOL &&
     925             :                            EXPECTED(Z_TYPE_P(arg) == IS_FALSE || Z_TYPE_P(arg) == IS_TRUE)) {
     926          10 :                 return 1;
     927             :         } else {
     928         482 :                 return zend_verify_scalar_type_hint(arg_info->type_hint, arg,
     929         241 :                         is_return_type ? ZEND_RET_USES_STRICT_TYPES() : ZEND_ARG_USES_STRICT_TYPES());
     930             :         }
     931             : 
     932             :         /* Special handling for IS_VOID is not necessary (for return types),
     933             :          * because this case is already checked at compile-time. */
     934             : }
     935             : 
     936             : static zend_always_inline int zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value, void **cache_slot)
     937             : {
     938             :         zend_arg_info *cur_arg_info;
     939             :         zend_class_entry *ce;
     940             : 
     941       88681 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     942       88671 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     943          10 :         } else if (UNEXPECTED(zf->common.fn_flags & ZEND_ACC_VARIADIC)) {
     944          10 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args];
     945             :         } else {
     946           0 :                 return 1;
     947             :         }
     948             : 
     949       88681 :         if (UNEXPECTED(!zend_check_type(zf, cur_arg_info, arg, &ce, cache_slot, default_value, 0))) {
     950         159 :                 zend_verify_arg_error(zf, cur_arg_info, arg_num, ce, arg);
     951         159 :                 return 0;
     952             :         }
     953             : 
     954       88522 :         return 1;
     955             : }
     956             : 
     957          58 : ZEND_API ZEND_COLD void ZEND_FASTCALL zend_missing_arg_error(zend_execute_data *execute_data)
     958             : {
     959          58 :         zend_execute_data *ptr = EX(prev_execute_data);
     960             : 
     961          85 :         if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     962         192 :                 zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected",
     963          30 :                         EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "",
     964          27 :                         EX(func)->common.scope ? "::" : "",
     965          27 :                         ZSTR_VAL(EX(func)->common.function_name),
     966             :                         EX_NUM_ARGS(),
     967          27 :                         ZSTR_VAL(ptr->func->op_array.filename),
     968          27 :                         ptr->opline->lineno,
     969          27 :                         EX(func)->common.required_num_args == EX(func)->common.num_args ? "exactly" : "at least",
     970          27 :                         EX(func)->common.required_num_args);
     971             :         } else {
     972         165 :                 zend_throw_error(zend_ce_argument_count_error, "Too few arguments to function %s%s%s(), %d passed and %s %d expected",
     973          41 :                         EX(func)->common.scope ? ZSTR_VAL(EX(func)->common.scope->name) : "",
     974          31 :                         EX(func)->common.scope ? "::" : "",
     975          31 :                         ZSTR_VAL(EX(func)->common.function_name),
     976             :                         EX_NUM_ARGS(),
     977          31 :                         EX(func)->common.required_num_args == EX(func)->common.num_args ? "exactly" : "at least",
     978          31 :                         EX(func)->common.required_num_args);
     979             :         }
     980          58 : }
     981             : 
     982          56 : static ZEND_COLD void zend_verify_return_error(
     983             :                 const zend_function *zf, const zend_class_entry *ce, zval *value)
     984             : {
     985          56 :         const zend_arg_info *arg_info = &zf->common.arg_info[-1];
     986             :         const char *fname, *fsep, *fclass;
     987             :         const char *need_msg, *need_kind, *need_or_null, *given_msg, *given_kind;
     988             : 
     989          56 :         zend_verify_type_error_common(
     990             :                 zf, arg_info, ce, value,
     991             :                 &fname, &fsep, &fclass, &need_msg, &need_kind, &need_or_null, &given_msg, &given_kind); 
     992             : 
     993          56 :         zend_type_error("Return value of %s%s%s() must %s%s%s, %s%s returned",
     994             :                 fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind);
     995          56 : }
     996             : 
     997             : #if ZEND_DEBUG
     998             : static ZEND_COLD void zend_verify_internal_return_error(
     999             :                 const zend_function *zf, const zend_class_entry *ce, zval *value)
    1000             : {
    1001             :         const zend_arg_info *arg_info = &zf->common.arg_info[-1];
    1002             :         const char *fname, *fsep, *fclass;
    1003             :         const char *need_msg, *need_kind, *need_or_null, *given_msg, *given_kind;
    1004             : 
    1005             :         zend_verify_type_error_common(
    1006             :                 zf, arg_info, ce, value,
    1007             :                 &fname, &fsep, &fclass, &need_msg, &need_kind, &need_or_null, &given_msg, &given_kind); 
    1008             : 
    1009             :         zend_error_noreturn(E_CORE_ERROR, "Return value of %s%s%s() must %s%s%s, %s%s returned",
    1010             :                 fclass, fsep, fname, need_msg, need_kind, need_or_null, given_msg, given_kind);
    1011             : }
    1012             : 
    1013             : static ZEND_COLD void zend_verify_void_return_error(const zend_function *zf, const char *returned_msg, const char *returned_kind)
    1014             : {
    1015             :         const char *fname = ZSTR_VAL(zf->common.function_name);
    1016             :         const char *fsep;
    1017             :         const char *fclass;
    1018             : 
    1019             :         if (zf->common.scope) {
    1020             :                 fsep =  "::";
    1021             :                 fclass = ZSTR_VAL(zf->common.scope->name);
    1022             :         } else {
    1023             :                 fsep =  "";
    1024             :                 fclass = "";
    1025             :         }
    1026             : 
    1027             :         zend_type_error("%s%s%s() must not return a value, %s%s returned",
    1028             :                 fclass, fsep, fname, returned_msg, returned_kind);
    1029             : }
    1030             : 
    1031             : static int zend_verify_internal_return_type(zend_function *zf, zval *ret)
    1032             : {
    1033             :         zend_internal_arg_info *ret_info = zf->internal_function.arg_info - 1;
    1034             :         zend_class_entry *ce = NULL;
    1035             : 
    1036             :         if (UNEXPECTED(ret_info->type_hint == IS_VOID && Z_TYPE_P(ret) != IS_NULL)) {
    1037             :                 zend_verify_void_return_error(zf, zend_zval_type_name(ret), "");
    1038             :                 return 0;
    1039             :         }
    1040             : 
    1041             :         if (UNEXPECTED(!zend_check_internal_type(zf, ret_info, ret, &ce, 1))) {
    1042             :                 zend_verify_internal_return_error(zf, ce, ret);
    1043             :                 return 0;
    1044             :         }
    1045             : 
    1046             :         return 1;
    1047             : }
    1048             : #endif
    1049             : 
    1050             : static zend_always_inline void zend_verify_return_type(zend_function *zf, zval *ret, void **cache_slot)
    1051             : {
    1052         148 :         zend_arg_info *ret_info = zf->common.arg_info - 1;
    1053         148 :         zend_class_entry *ce = NULL;
    1054             :         
    1055         148 :         if (UNEXPECTED(!zend_check_type(zf, ret_info, ret, &ce, cache_slot, NULL, 1))) {
    1056          49 :                 zend_verify_return_error(zf, ce, ret);
    1057             :         }
    1058             : }
    1059             : 
    1060           7 : static ZEND_COLD int zend_verify_missing_return_type(zend_function *zf, void **cache_slot)
    1061             : {
    1062           7 :         zend_arg_info *ret_info = zf->common.arg_info - 1;
    1063             : 
    1064           7 :         if (ret_info->type_hint && UNEXPECTED(ret_info->type_hint != IS_VOID)) {
    1065           7 :                 zend_class_entry *ce = NULL;
    1066           7 :                 if (ret_info->class_name) {
    1067           3 :                         if (EXPECTED(*cache_slot)) {
    1068           0 :                                 ce = (zend_class_entry*) *cache_slot;
    1069             :                         } else {
    1070           3 :                                 ce = zend_verify_arg_class_kind(ret_info);
    1071           3 :                                 if (ce) {
    1072           2 :                                         *cache_slot = (void*)ce;
    1073             :                                 }
    1074             :                         }
    1075             :                 }
    1076           7 :                 zend_verify_return_error(zf, ce, NULL);
    1077           7 :                 return 0;
    1078             :         }
    1079           0 :         return 1;
    1080             : }
    1081             : 
    1082        1582 : static zend_never_inline void zend_assign_to_object_dim(zval *object, zval *dim, zval *value)
    1083             : {
    1084        1582 :         if (UNEXPECTED(!Z_OBJ_HT_P(object)->write_dimension)) {
    1085           0 :                 zend_throw_error(NULL, "Cannot use object as array");
    1086           0 :                 return;
    1087             :         }
    1088             : 
    1089        1582 :         Z_OBJ_HT_P(object)->write_dimension(object, dim, value);
    1090             : }
    1091             : 
    1092          13 : static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval *property, zval *value, zval *retval, binary_op_type binary_op)
    1093             : {
    1094             :         zval *z;
    1095             :         zval rv, res;
    1096             : 
    1097          39 :         if (Z_OBJ_HT_P(object)->read_dimension &&
    1098          13 :                 (z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) {
    1099             : 
    1100          13 :                 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
    1101             :                         zval rv2;
    1102           4 :                         zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
    1103             : 
    1104           4 :                         if (z == &rv) {
    1105             :                                 zval_ptr_dtor(&rv);
    1106             :                         }
    1107           4 :                         ZVAL_COPY_VALUE(z, value);
    1108             :                 }
    1109          13 :                 binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value);
    1110          13 :                 Z_OBJ_HT_P(object)->write_dimension(object, property, &res);
    1111          13 :                 if (z == &rv) {
    1112             :                         zval_ptr_dtor(&rv);
    1113             :                 }
    1114          13 :                 if (retval) {
    1115           1 :                         ZVAL_COPY(retval, &res);
    1116             :                 }
    1117             :                 zval_ptr_dtor(&res);
    1118             :         } else {
    1119           0 :                 zend_error(E_WARNING, "Attempt to assign property of non-object");
    1120           0 :                 if (retval) {
    1121           0 :                         ZVAL_NULL(retval);
    1122             :                 }
    1123             :         }
    1124          13 : }
    1125             : 
    1126         185 : static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type)
    1127             : {
    1128             :         zend_long offset;
    1129             : 
    1130             : try_again:
    1131         185 :         if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1132          17 :                 switch(Z_TYPE_P(dim)) {
    1133             :                         case IS_STRING:
    1134          34 :                                 if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1135           0 :                                         break;
    1136             :                                 }
    1137          17 :                                 if (type != BP_VAR_UNSET) {
    1138          16 :                                         zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1139             :                                 }
    1140          17 :                                 break;
    1141             :                         case IS_UNDEF:
    1142           0 :                                 zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1143             :                         case IS_DOUBLE:
    1144             :                         case IS_NULL:
    1145             :                         case IS_FALSE:
    1146             :                         case IS_TRUE:
    1147           0 :                                 zend_error(E_NOTICE, "String offset cast occurred");
    1148           0 :                                 break;
    1149             :                         case IS_REFERENCE:
    1150           0 :                                 dim = Z_REFVAL_P(dim);
    1151           0 :                                 goto try_again;
    1152             :                         default:
    1153           0 :                                 zend_error(E_WARNING, "Illegal offset type");
    1154             :                                 break;
    1155             :                 }
    1156             : 
    1157          17 :                 offset = _zval_get_long_func(dim);
    1158             :         } else {
    1159         168 :                 offset = Z_LVAL_P(dim);
    1160             :         }
    1161             : 
    1162         185 :         return offset;
    1163             : }
    1164             : 
    1165          15 : static zend_never_inline ZEND_COLD void zend_wrong_string_offset(void)
    1166             : {
    1167          15 :         const char *msg = NULL;
    1168          15 :         const zend_op *opline = EG(current_execute_data)->opline;
    1169             :         const zend_op *end;
    1170             :         uint32_t var;
    1171             : 
    1172          15 :         switch (opline->opcode) {
    1173             :                 case ZEND_ASSIGN_ADD:
    1174             :                 case ZEND_ASSIGN_SUB:
    1175             :                 case ZEND_ASSIGN_MUL:
    1176             :                 case ZEND_ASSIGN_DIV:
    1177             :                 case ZEND_ASSIGN_MOD:
    1178             :                 case ZEND_ASSIGN_SL:
    1179             :                 case ZEND_ASSIGN_SR:
    1180             :                 case ZEND_ASSIGN_CONCAT:
    1181             :                 case ZEND_ASSIGN_BW_OR:
    1182             :                 case ZEND_ASSIGN_BW_AND:
    1183             :                 case ZEND_ASSIGN_BW_XOR:
    1184             :                 case ZEND_ASSIGN_POW:
    1185           1 :                         msg = "Cannot use assign-op operators with string offsets";
    1186           1 :                         break;
    1187             :                 case ZEND_FETCH_DIM_W:
    1188             :                 case ZEND_FETCH_DIM_RW:
    1189             :                 case ZEND_FETCH_DIM_FUNC_ARG:
    1190             :                 case ZEND_FETCH_DIM_UNSET:
    1191             :                         /* TODO: Encode the "reason" into opline->extended_value??? */
    1192          14 :                         var = opline->result.var;
    1193          14 :                         opline++;
    1194          42 :                         end = EG(current_execute_data)->func->op_array.opcodes +
    1195          28 :                                 EG(current_execute_data)->func->op_array.last;
    1196          28 :                         while (opline < end) {
    1197          14 :                                 if (opline->op1_type == IS_VAR && opline->op1.var == var) {
    1198          13 :                                         switch (opline->opcode) {
    1199             :                                                 case ZEND_ASSIGN_ADD:
    1200             :                                                 case ZEND_ASSIGN_SUB:
    1201             :                                                 case ZEND_ASSIGN_MUL:
    1202             :                                                 case ZEND_ASSIGN_DIV:
    1203             :                                                 case ZEND_ASSIGN_MOD:
    1204             :                                                 case ZEND_ASSIGN_SL:
    1205             :                                                 case ZEND_ASSIGN_SR:
    1206             :                                                 case ZEND_ASSIGN_CONCAT:
    1207             :                                                 case ZEND_ASSIGN_BW_OR:
    1208             :                                                 case ZEND_ASSIGN_BW_AND:
    1209             :                                                 case ZEND_ASSIGN_BW_XOR:
    1210             :                                                 case ZEND_ASSIGN_POW:
    1211           2 :                                                         if (opline->extended_value == ZEND_ASSIGN_OBJ) {
    1212           1 :                                                                 msg = "Cannot use string offset as an object";
    1213           1 :                                                         } else if (opline->extended_value == ZEND_ASSIGN_DIM) {
    1214           1 :                                                                 msg = "Cannot use string offset as an array";
    1215             :                                                         } else {
    1216           0 :                                                                 msg = "Cannot use assign-op operators with string offsets";
    1217             :                                                         }
    1218           2 :                                                         break;
    1219             :                                                 case ZEND_PRE_INC_OBJ:
    1220             :                                                 case ZEND_PRE_DEC_OBJ:
    1221             :                                                 case ZEND_POST_INC_OBJ:
    1222             :                                                 case ZEND_POST_DEC_OBJ:
    1223             :                                                 case ZEND_PRE_INC:
    1224             :                                                 case ZEND_PRE_DEC:
    1225             :                                                 case ZEND_POST_INC:
    1226             :                                                 case ZEND_POST_DEC:
    1227           1 :                                                         msg = "Cannot increment/decrement string offsets";
    1228           1 :                                                         break;
    1229             :                                                 case ZEND_FETCH_DIM_W:
    1230             :                                                 case ZEND_FETCH_DIM_RW:
    1231             :                                                 case ZEND_FETCH_DIM_FUNC_ARG:
    1232             :                                                 case ZEND_FETCH_DIM_UNSET:
    1233             :                                                 case ZEND_ASSIGN_DIM:
    1234           3 :                                                         msg = "Cannot use string offset as an array";
    1235           3 :                                                         break;
    1236             :                                                 case ZEND_FETCH_OBJ_W:
    1237             :                                                 case ZEND_FETCH_OBJ_RW:
    1238             :                                                 case ZEND_FETCH_OBJ_FUNC_ARG:
    1239             :                                                 case ZEND_FETCH_OBJ_UNSET:
    1240             :                                                 case ZEND_ASSIGN_OBJ:
    1241           2 :                                                         msg = "Cannot use string offset as an object";
    1242           2 :                                                         break;
    1243             :                                                 case ZEND_ASSIGN_REF:
    1244             :                                                 case ZEND_ADD_ARRAY_ELEMENT:
    1245             :                                                 case ZEND_INIT_ARRAY:
    1246             :                                                 case ZEND_MAKE_REF:
    1247           2 :                                                         msg = "Cannot create references to/from string offsets";
    1248           2 :                                                         break;
    1249             :                                                 case ZEND_RETURN_BY_REF:
    1250             :                                                 case ZEND_VERIFY_RETURN_TYPE:
    1251           1 :                                                         msg = "Cannot return string offsets by reference";
    1252           1 :                                                         break;
    1253             :                                                 case ZEND_UNSET_DIM:
    1254             :                                                 case ZEND_UNSET_OBJ:
    1255           1 :                                                         msg = "Cannot unset string offsets";
    1256           1 :                                                         break;
    1257             :                                                 case ZEND_YIELD:
    1258           0 :                                                         msg = "Cannot yield string offsets by reference";
    1259           0 :                                                         break;
    1260             :                                                 case ZEND_SEND_REF:
    1261             :                                                 case ZEND_SEND_VAR_EX:
    1262           1 :                                                         msg = "Only variables can be passed by reference";
    1263             :                                                         break;
    1264             :                                                 EMPTY_SWITCH_DEFAULT_CASE();
    1265             :                                         }
    1266          13 :                                         break;
    1267             :                                 }
    1268           1 :                                 if (opline->op2_type == IS_VAR && opline->op2.var == var) {
    1269             :                                         ZEND_ASSERT(opline->opcode == ZEND_ASSIGN_REF);
    1270           1 :                                         msg = "Cannot create references to/from string offsets";
    1271           1 :                                         break;
    1272             :                                 }
    1273             :                         }
    1274             :                         break;
    1275             :                 EMPTY_SWITCH_DEFAULT_CASE();
    1276             :         }
    1277             :         ZEND_ASSERT(msg != NULL);
    1278          15 :         zend_throw_error(NULL, msg);
    1279          15 : }
    1280             : 
    1281         170 : static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value, zval *result)
    1282             : {
    1283             :         zend_string *old_str;
    1284             :         zend_uchar c;
    1285             :         size_t string_len;
    1286             :         zend_long offset;
    1287             : 
    1288         170 :         offset = zend_check_string_offset(dim, BP_VAR_W);
    1289         170 :         if (offset < -(zend_long)Z_STRLEN_P(str)) {
    1290             :                 /* Error on negative offset */
    1291           2 :                 zend_error(E_WARNING, "Illegal string offset:  " ZEND_LONG_FMT, offset);
    1292           2 :                 if (result) {
    1293           1 :                         ZVAL_NULL(result);
    1294             :                 }
    1295           2 :                 return;
    1296             :         }
    1297             : 
    1298         168 :         if (Z_TYPE_P(value) != IS_STRING) {
    1299             :                 /* Convert to string, just the time to pick the 1st byte */
    1300          12 :                 zend_string *tmp = zval_get_string(value);
    1301             : 
    1302          12 :                 string_len = ZSTR_LEN(tmp);
    1303          12 :                 c = (zend_uchar)ZSTR_VAL(tmp)[0];
    1304             :                 zend_string_release(tmp);
    1305             :         } else {
    1306         156 :                 string_len = Z_STRLEN_P(value);
    1307         156 :                 c = (zend_uchar)Z_STRVAL_P(value)[0];
    1308             :         }
    1309             : 
    1310         168 :         if (string_len == 0) {
    1311             :                 /* Error on empty input string */
    1312           4 :                 zend_error(E_WARNING, "Cannot assign an empty string to a string offset");
    1313           4 :                 if (result) {
    1314           4 :                         ZVAL_NULL(result);
    1315             :                 }
    1316           4 :                 return;
    1317             :         }
    1318             : 
    1319         164 :         if (offset < 0) { /* Handle negative offset */
    1320           7 :                 offset += (zend_long)Z_STRLEN_P(str);
    1321             :         }
    1322             : 
    1323         164 :         if ((size_t)offset >= Z_STRLEN_P(str)) {
    1324             :                 /* Extend string if needed */
    1325           8 :                 zend_long old_len = Z_STRLEN_P(str);
    1326          16 :                 Z_STR_P(str) = zend_string_extend(Z_STR_P(str), offset + 1, 0);
    1327           8 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    1328           8 :                 memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
    1329           8 :                 Z_STRVAL_P(str)[offset+1] = 0;
    1330         156 :         } else if (!Z_REFCOUNTED_P(str)) {
    1331          10 :                 old_str = Z_STR_P(str);
    1332          20 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    1333          10 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    1334             :                 zend_string_release(old_str);
    1335             :         } else {
    1336         298 :                 SEPARATE_STRING(str);
    1337         146 :                 zend_string_forget_hash_val(Z_STR_P(str));
    1338             :         }
    1339             : 
    1340         164 :         Z_STRVAL_P(str)[offset] = c;
    1341             : 
    1342         164 :         if (result) {
    1343             :                 /* Return the new character */
    1344          17 :                 if (CG(one_char_string)[c]) {
    1345           0 :                         ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1346             :                 } else {
    1347          34 :                         ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(str) + offset, 1, 0));
    1348             :                 }
    1349             :         }
    1350             : }
    1351             : 
    1352           9 : static zend_never_inline void zend_post_incdec_overloaded_property(zval *object, zval *property, void **cache_slot, int inc, zval *result)
    1353             : {
    1354          17 :         if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
    1355             :                 zval rv, obj;
    1356             :                 zval *z;
    1357             :                 zval z_copy;
    1358             : 
    1359           9 :                 ZVAL_OBJ(&obj, Z_OBJ_P(object));
    1360             :                 Z_ADDREF(obj);
    1361           9 :                 z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
    1362           9 :                 if (UNEXPECTED(EG(exception))) {
    1363           1 :                         OBJ_RELEASE(Z_OBJ(obj));
    1364           1 :                         return;
    1365             :                 }
    1366             : 
    1367           8 :                 if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
    1368             :                         zval rv2;
    1369           0 :                         zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
    1370           0 :                         if (z == &rv) {
    1371             :                                 zval_ptr_dtor(&rv);
    1372             :                         }
    1373           0 :                         ZVAL_COPY_VALUE(z, value);
    1374             :                 }
    1375             : 
    1376           8 :                 if (UNEXPECTED(Z_TYPE_P(z) == IS_REFERENCE)) {
    1377           1 :                         ZVAL_COPY(result, Z_REFVAL_P(z));
    1378             :                 } else {
    1379           7 :                         ZVAL_COPY(result, z);
    1380             :                 }
    1381           8 :                 ZVAL_DUP(&z_copy, result);
    1382           8 :                 if (inc) {
    1383           8 :                         increment_function(&z_copy);
    1384             :                 } else {
    1385           0 :                         decrement_function(&z_copy);
    1386             :                 }
    1387           8 :                 Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, cache_slot);
    1388           8 :                 OBJ_RELEASE(Z_OBJ(obj));
    1389             :                 zval_ptr_dtor(&z_copy);
    1390             :                 zval_ptr_dtor(z);
    1391             :         } else {
    1392           0 :                 zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
    1393           0 :                 ZVAL_NULL(result);
    1394             :         }
    1395             : }
    1396             : 
    1397           5 : static zend_never_inline void zend_pre_incdec_overloaded_property(zval *object, zval *property, void **cache_slot, int inc, zval *result)
    1398             : {
    1399             :         zval rv;
    1400             : 
    1401           8 :         if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
    1402             :                 zval *z, obj;
    1403             :                                 
    1404           5 :                 ZVAL_OBJ(&obj, Z_OBJ_P(object));
    1405             :                 Z_ADDREF(obj);
    1406           5 :                 z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
    1407           5 :                 if (UNEXPECTED(EG(exception))) {
    1408           2 :                         OBJ_RELEASE(Z_OBJ(obj));
    1409           2 :                         return;
    1410             :                 }
    1411             : 
    1412           3 :                 if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
    1413             :                         zval rv2;
    1414           0 :                         zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
    1415             : 
    1416           0 :                         if (z == &rv) {
    1417             :                                 zval_ptr_dtor(&rv);
    1418             :                         }
    1419           0 :                         ZVAL_COPY_VALUE(z, value);
    1420             :                 }
    1421           3 :                 ZVAL_DEREF(z);
    1422           3 :                 SEPARATE_ZVAL_NOREF(z);
    1423           3 :                 if (inc) {
    1424           3 :                         increment_function(z);
    1425             :                 } else {
    1426           0 :                         decrement_function(z);
    1427             :                 }
    1428           3 :                 if (UNEXPECTED(result)) {
    1429           1 :                         ZVAL_COPY(result, z);
    1430             :                 }
    1431           3 :                 Z_OBJ_HT(obj)->write_property(&obj, property, z, cache_slot);
    1432           3 :                 OBJ_RELEASE(Z_OBJ(obj));
    1433             :                 zval_ptr_dtor(z);
    1434             :         } else {
    1435           0 :                 zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
    1436           0 :                 if (UNEXPECTED(result)) {
    1437           0 :                         ZVAL_NULL(result);
    1438             :                 }
    1439             :         }
    1440             : }
    1441             : 
    1442           9 : static zend_never_inline void zend_assign_op_overloaded_property(zval *object, zval *property, void **cache_slot, zval *value, binary_op_type binary_op, zval *result)
    1443             : {
    1444             :         zval *z;
    1445             :         zval rv, obj;
    1446             :         zval *zptr;
    1447             : 
    1448           9 :         ZVAL_OBJ(&obj, Z_OBJ_P(object));
    1449             :         Z_ADDREF(obj);
    1450           9 :         if (EXPECTED(Z_OBJ_HT(obj)->read_property)) {
    1451           9 :                 z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
    1452           9 :                 if (UNEXPECTED(EG(exception))) {
    1453           1 :                         OBJ_RELEASE(Z_OBJ(obj));
    1454           1 :                         return;
    1455             :                 }
    1456           8 :                 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
    1457             :                         zval rv2;
    1458           3 :                         zval *value = Z_OBJ_HT_P(z)->get(z, &rv2);
    1459             : 
    1460           3 :                         if (z == &rv) {
    1461             :                                 zval_ptr_dtor(&rv);
    1462             :                         }
    1463           3 :                         ZVAL_COPY_VALUE(z, value);
    1464             :                 }
    1465           8 :                 zptr = z;
    1466           8 :                 ZVAL_DEREF(z);
    1467          10 :                 SEPARATE_ZVAL_NOREF(z);
    1468           8 :                 binary_op(z, z, value);
    1469           8 :                 Z_OBJ_HT(obj)->write_property(&obj, property, z, cache_slot);
    1470           8 :                 if (UNEXPECTED(result)) {
    1471           0 :                         ZVAL_COPY(result, z);
    1472             :                 }
    1473             :                 zval_ptr_dtor(zptr);
    1474             :         } else {
    1475           0 :                 zend_error(E_WARNING, "Attempt to assign property of non-object");
    1476           0 :                 if (UNEXPECTED(result)) {
    1477           0 :                         ZVAL_NULL(result);
    1478             :                 }
    1479             :         }
    1480           8 :         OBJ_RELEASE(Z_OBJ(obj));
    1481             : }
    1482             : 
    1483             : /* Utility Functions for Extensions */
    1484           0 : static void zend_extension_statement_handler(const zend_extension *extension, zend_execute_data *frame)
    1485             : {
    1486           0 :         if (extension->statement_handler) {
    1487           0 :                 extension->statement_handler(frame);
    1488             :         }
    1489           0 : }
    1490             : 
    1491             : 
    1492           0 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_execute_data *frame)
    1493             : {
    1494           0 :         if (extension->fcall_begin_handler) {
    1495           0 :                 extension->fcall_begin_handler(frame);
    1496             :         }
    1497           0 : }
    1498             : 
    1499             : 
    1500           0 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_execute_data *frame)
    1501             : {
    1502           0 :         if (extension->fcall_end_handler) {
    1503           0 :                 extension->fcall_end_handler(frame);
    1504             :         }
    1505           0 : }
    1506             : 
    1507             : 
    1508             : static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_data *execute_data, int fetch_type)
    1509             : {
    1510             :         HashTable *ht;
    1511             : 
    1512      458297 :         if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
    1513      229146 :             EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
    1514      124054 :                 ht = &EG(symbol_table);
    1515             :         } else {
    1516             :                 ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
    1517      105097 :                 if (!(EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE)) {
    1518          14 :                         zend_rebuild_symbol_table();
    1519             :                 }
    1520      105097 :                 ht = EX(symbol_table);
    1521             :         }
    1522      229151 :         return ht;
    1523             : }
    1524             : 
    1525             : static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type)
    1526             : {
    1527             :         zval *retval;
    1528             :         zend_string *offset_key;
    1529             :         zend_ulong hval;
    1530             : 
    1531             : try_again:
    1532    10613536 :         if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
    1533     4840457 :                 hval = Z_LVAL_P(dim);
    1534             : num_index:
    1535     9109957 :                 ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef);
    1536     4622908 :                 return retval;
    1537             : num_undef:
    1538      397713 :                 switch (type) {
    1539             :                         case BP_VAR_R:
    1540          21 :                                 zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
    1541             :                                 /* break missing intentionally */
    1542             :                         case BP_VAR_UNSET:
    1543             :                         case BP_VAR_IS:
    1544          30 :                                 retval = &EG(uninitialized_zval);
    1545             :                                 break;
    1546             :                         case BP_VAR_RW:
    1547           6 :                                 zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval);
    1548           6 :                                 retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
    1549             :                                 break;
    1550             :                         case BP_VAR_W:
    1551      397677 :                                 retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
    1552             :                                 break;
    1553             :                 }
    1554     5773079 :         } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
    1555     4562099 :                 offset_key = Z_STR_P(dim);
    1556     4562099 :                 if (dim_type != IS_CONST) {
    1557     6945538 :                         if (ZEND_HANDLE_NUMERIC(offset_key, hval)) {
    1558             :                                 goto num_index;
    1559             :                         }
    1560             :                 }
    1561             : str_index:
    1562     4382024 :                 retval = zend_hash_find(ht, offset_key);
    1563     4382024 :                 if (retval) {
    1564             :                         /* support for $GLOBALS[...] */
    1565     2087652 :                         if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
    1566        7986 :                                 retval = Z_INDIRECT_P(retval);
    1567        7986 :                                 if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
    1568          22 :                                         switch (type) {
    1569             :                                                 case BP_VAR_R:
    1570           1 :                                                         zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(offset_key));
    1571             :                                                         /* break missing intentionally */
    1572             :                                                 case BP_VAR_UNSET:
    1573             :                                                 case BP_VAR_IS:
    1574           1 :                                                         retval = &EG(uninitialized_zval);
    1575             :                                                         break;
    1576             :                                                 case BP_VAR_RW:
    1577           0 :                                                         zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(offset_key));
    1578             :                                                         /* break missing intentionally */
    1579             :                                                 case BP_VAR_W:
    1580          21 :                                                         ZVAL_NULL(retval);
    1581             :                                                         break;
    1582             :                                         }
    1583             :                                 }
    1584             :                         }
    1585             :                 } else {
    1586     2294372 :                         switch (type) {
    1587             :                                 case BP_VAR_R:
    1588      184080 :                                         zend_error(E_NOTICE, "Undefined index: %s", ZSTR_VAL(offset_key));
    1589             :                                         /* break missing intentionally */
    1590             :                                 case BP_VAR_UNSET:
    1591             :                                 case BP_VAR_IS:
    1592      184086 :                                         retval = &EG(uninitialized_zval);
    1593             :                                         break;
    1594             :                                 case BP_VAR_RW:
    1595           2 :                                         zend_error(E_NOTICE,"Undefined index: %s", ZSTR_VAL(offset_key));
    1596           2 :                                         retval = zend_hash_update(ht, offset_key, &EG(uninitialized_zval));
    1597             :                                         break;
    1598             :                                 case BP_VAR_W:
    1599     2110284 :                                         retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
    1600             :                                         break;
    1601             :                         }
    1602             :                 }
    1603             :         } else {
    1604     1210980 :                 switch (Z_TYPE_P(dim)) {
    1605             :                         case IS_UNDEF:
    1606           2 :                                 zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1607             :                                 /* break missing intentionally */                               
    1608             :                         case IS_NULL:
    1609          14 :                                 offset_key = ZSTR_EMPTY_ALLOC();
    1610             :                                 goto str_index;
    1611             :                         case IS_DOUBLE:
    1612         118 :                                 hval = zend_dval_to_lval(Z_DVAL_P(dim));
    1613             :                                 goto num_index;
    1614             :                         case IS_RESOURCE:
    1615           4 :                                 zend_error(E_NOTICE, "Resource ID#%d used as offset, casting to integer (%d)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
    1616           4 :                                 hval = Z_RES_HANDLE_P(dim);
    1617             :                                 goto num_index;
    1618             :                         case IS_FALSE:
    1619           7 :                                 hval = 0;
    1620             :                                 goto num_index;
    1621             :                         case IS_TRUE:
    1622           5 :                                 hval = 1;
    1623             :                                 goto num_index;
    1624             :                         case IS_REFERENCE:
    1625     1210881 :                                 dim = Z_REFVAL_P(dim);
    1626             :                                 goto try_again;
    1627             :                         default:
    1628          10 :                                 zend_error(E_WARNING, "Illegal offset type");
    1629          10 :                                 retval = (type == BP_VAR_W || type == BP_VAR_RW) ?
    1630             :                                         NULL : &EG(uninitialized_zval);
    1631             :                 }
    1632             :         }
    1633     4779747 :         return retval;
    1634             : }
    1635             : 
    1636     2427019 : static zend_never_inline zval* ZEND_FASTCALL zend_fetch_dimension_address_inner_W(HashTable *ht, const zval *dim)
    1637             : {
    1638     2427019 :         return zend_fetch_dimension_address_inner(ht, dim, IS_TMP_VAR, BP_VAR_W);
    1639             : }
    1640             : 
    1641      322763 : static zend_never_inline zval* ZEND_FASTCALL zend_fetch_dimension_address_inner_W_CONST(HashTable *ht, const zval *dim)
    1642             : {
    1643      322763 :         return zend_fetch_dimension_address_inner(ht, dim, IS_CONST, BP_VAR_W);
    1644             : }
    1645             : 
    1646     1181279 : static zend_never_inline zval* ZEND_FASTCALL zend_fetch_dimension_address_inner_RW(HashTable *ht, const zval *dim)
    1647             : {
    1648     1181279 :         return zend_fetch_dimension_address_inner(ht, dim, IS_TMP_VAR, BP_VAR_RW);
    1649             : }
    1650             : 
    1651          44 : static zend_never_inline zval* ZEND_FASTCALL zend_fetch_dimension_address_inner_RW_CONST(HashTable *ht, const zval *dim)
    1652             : {
    1653          44 :         return zend_fetch_dimension_address_inner(ht, dim, IS_CONST, BP_VAR_RW);
    1654             : }
    1655             : 
    1656             : static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container, zval *dim, int dim_type, int type)
    1657             : {
    1658             :     zval *retval;
    1659             : 
    1660      568981 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1661             : try_array:
    1662      568536 :                 SEPARATE_ARRAY(container);
    1663             : fetch_from_array:
    1664      568902 :                 if (dim == NULL) {
    1665       96560 :                         retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
    1666       96560 :                         if (UNEXPECTED(retval == NULL)) {
    1667           2 :                                 zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
    1668           2 :                                 ZVAL_ERROR(result);
    1669             :                                 return;
    1670             :                         }
    1671             :                 } else {
    1672      944684 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
    1673      472342 :                         if (UNEXPECTED(!retval)) {
    1674           0 :                                 ZVAL_ERROR(result);
    1675             :                                 return;
    1676             :                         }
    1677             :                 }
    1678      568900 :                 ZVAL_INDIRECT(result, retval);
    1679             :                 return;
    1680       64182 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
    1681       63738 :                 container = Z_REFVAL_P(container);
    1682       63738 :                 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1683             :                         goto try_array;
    1684             :                 }
    1685             :         }
    1686         445 :         if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1687          15 :                 if (dim == NULL) {
    1688           1 :                         zend_throw_error(NULL, "[] operator not supported for strings");
    1689             :                 } else {
    1690          14 :                         zend_check_string_offset(dim, type);
    1691          14 :                         zend_wrong_string_offset();
    1692             :                 }
    1693          15 :                 ZVAL_ERROR(result);
    1694         430 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1695         104 :                 if (/*dim_type == IS_CV &&*/ dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
    1696           0 :                         zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1697           0 :                         dim = &EG(uninitialized_zval);
    1698             :                 }
    1699          56 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1700           0 :                         zend_throw_error(NULL, "Cannot use object as array");
    1701           0 :                         ZVAL_ERROR(result);
    1702             :                 } else {
    1703          56 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result);
    1704             : 
    1705          56 :                         if (UNEXPECTED(retval == &EG(uninitialized_zval))) {
    1706           2 :                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1707             : 
    1708           2 :                                 ZVAL_NULL(result);
    1709           2 :                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name));
    1710         104 :                         } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) {
    1711          50 :                                 if (!Z_ISREF_P(retval)) {
    1712          76 :                                         if (Z_REFCOUNTED_P(retval) &&
    1713             :                                             Z_REFCOUNT_P(retval) > 1) {
    1714           7 :                                                 if (Z_TYPE_P(retval) != IS_OBJECT) {
    1715             :                                                         Z_DELREF_P(retval);
    1716           5 :                                                         ZVAL_DUP(result, retval);
    1717           5 :                                                         retval = result;
    1718             :                                                 } else {
    1719           2 :                                                         ZVAL_COPY_VALUE(result, retval);
    1720           2 :                                                         retval = result;
    1721             :                                                 }
    1722             :                                         }
    1723          40 :                                         if (Z_TYPE_P(retval) != IS_OBJECT) {
    1724           9 :                                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1725           9 :                                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name));
    1726             :                                         }
    1727          10 :                                 } else if (UNEXPECTED(Z_REFCOUNT_P(retval) == 1)) {
    1728           6 :                                         ZVAL_UNREF(retval);
    1729             :                                 }
    1730          50 :                                 if (result != retval) {
    1731           5 :                                         ZVAL_INDIRECT(result, retval);
    1732             :                                 }
    1733             :                         } else {
    1734           4 :                                 ZVAL_ERROR(result);
    1735             :                         }
    1736             :                 }
    1737             :         } else {
    1738         378 :                 if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
    1739           0 :                         zval_undefined_cv(EG(current_execute_data)->opline->op1.var, EG(current_execute_data));
    1740             :                 }
    1741         736 :                 if (/*dim_type == IS_CV &&*/ dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
    1742           0 :                         zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1743             :                 }
    1744         374 :                 if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
    1745         366 :                         if (type != BP_VAR_UNSET) {
    1746         366 :                                 ZVAL_NEW_ARR(container);
    1747         366 :                                 zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
    1748             :                                 goto fetch_from_array;
    1749             :                         } else {
    1750             :                                 /* for read-mode only */
    1751           0 :                                 ZVAL_NULL(result);
    1752             :                         }
    1753           8 :                 } else if (EXPECTED(Z_ISERROR_P(container))) {
    1754           0 :                         ZVAL_ERROR(result);
    1755             :                 } else {
    1756           8 :                         if (type == BP_VAR_UNSET) {
    1757           0 :                                 zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
    1758           0 :                                 ZVAL_NULL(result);
    1759             :                         } else {
    1760           8 :                                 zend_error(E_WARNING, "Cannot use a scalar value as an array");
    1761           8 :                                 ZVAL_ERROR(result);
    1762             :                         }
    1763             :                 }
    1764             :         }
    1765             : }
    1766             : 
    1767      370955 : static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1768             : {
    1769             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W);
    1770      370955 : }
    1771             : 
    1772      198003 : static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1773             : {
    1774             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW);
    1775      198003 : }
    1776             : 
    1777          23 : static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1778             : {
    1779             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET);
    1780          23 : }
    1781             : 
    1782             : static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type, int support_strings, int slow)
    1783             : {
    1784             :         zval *retval;
    1785             : 
    1786     2611667 :         if (!slow) {
    1787     2558623 :                 if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1788             : try_array:
    1789      417786 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
    1790      208893 :                         ZVAL_COPY(result, retval);
    1791             :                         return;
    1792     2349758 :                 } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
    1793          33 :                         container = Z_REFVAL_P(container);
    1794          33 :                         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1795             :                                 goto try_array;
    1796             :                         }
    1797             :                 }
    1798             :         }
    1799     4805434 :         if (support_strings && EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1800             :                 zend_long offset;
    1801             : 
    1802             : try_string_offset:
    1803     2401757 :                 if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1804          46 :                         switch (Z_TYPE_P(dim)) {
    1805             :                                 /* case IS_LONG: */
    1806             :                                 case IS_STRING:
    1807          60 :                                         if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1808             :                                                 break;
    1809             :                                         }
    1810          29 :                                         if (type == BP_VAR_IS) {
    1811           8 :                                                 ZVAL_NULL(result);
    1812             :                                                 return;
    1813             :                                         }
    1814          21 :                                         zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1815             :                                         break;
    1816             :                                 case IS_UNDEF:
    1817           0 :                                         zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1818             :                                 case IS_DOUBLE:
    1819             :                                 case IS_NULL:
    1820             :                                 case IS_FALSE:
    1821             :                                 case IS_TRUE:
    1822          13 :                                         if (type != BP_VAR_IS) {
    1823          11 :                                                 zend_error(E_NOTICE, "String offset cast occurred");
    1824             :                                         }
    1825             :                                         break;
    1826             :                                 case IS_REFERENCE:
    1827           0 :                                         dim = Z_REFVAL_P(dim);
    1828             :                                         goto try_string_offset;
    1829             :                                 default:
    1830           3 :                                         zend_error(E_WARNING, "Illegal offset type");
    1831             :                                         break;
    1832             :                         }
    1833             : 
    1834          38 :                         offset = _zval_get_long_func(dim);
    1835             :                 } else {
    1836     2401711 :                         offset = Z_LVAL_P(dim);
    1837             :                 }
    1838             : 
    1839     2401749 :                 if (UNEXPECTED(Z_STRLEN_P(container) < (size_t)((offset < 0) ? -offset : (offset + 1)))) {
    1840          37 :                         if (type != BP_VAR_IS) {
    1841          35 :                                 zend_error(E_NOTICE, "Uninitialized string offset: " ZEND_LONG_FMT, offset);
    1842          35 :                                 ZVAL_EMPTY_STRING(result);
    1843             :                         } else {
    1844           2 :                                 ZVAL_NULL(result);
    1845             :                         }
    1846             :                 } else {
    1847             :                         zend_uchar c;
    1848             :                         zend_long real_offset;
    1849             : 
    1850     2401717 :                         real_offset = (UNEXPECTED(offset < 0)) /* Handle negative offset */
    1851           5 :                                 ? (zend_long)Z_STRLEN_P(container) + offset : offset;
    1852     2401712 :                         c = (zend_uchar)Z_STRVAL_P(container)[real_offset];
    1853             : 
    1854     2401712 :                         if (CG(one_char_string)[c]) {
    1855           0 :                                 ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1856             :                         } else {
    1857     4803424 :                                 ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(container) + real_offset, 1, 0));
    1858             :                         }
    1859             :                 }
    1860        1017 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1861         811 :                 if (/*dim_type == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
    1862           0 :                         zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1863           0 :                         dim = &EG(uninitialized_zval);
    1864             :                 }
    1865         811 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1866           0 :                         zend_throw_error(NULL, "Cannot use object as array");
    1867           0 :                         ZVAL_NULL(result);
    1868             :                 } else {
    1869         811 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result);
    1870             : 
    1871             :                         ZEND_ASSERT(result != NULL);
    1872         811 :                         if (retval) {
    1873         800 :                                 if (result != retval) {
    1874         135 :                                         ZVAL_COPY(result, retval);
    1875             :                                 }
    1876             :                         } else {
    1877          11 :                                 ZVAL_NULL(result);
    1878             :                         }
    1879             :                 }
    1880             :         } else {
    1881         392 :                 if (type != BP_VAR_IS && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
    1882          15 :                         zval_undefined_cv(EG(current_execute_data)->opline->op1.var, EG(current_execute_data));
    1883             :                 }
    1884         206 :                 if (/*dim_type == IS_CV &&*/ UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
    1885           3 :                         zval_undefined_cv(EG(current_execute_data)->opline->op2.var, EG(current_execute_data));
    1886             :                 }
    1887         206 :                 ZVAL_NULL(result);
    1888             :         }
    1889             : }
    1890             : 
    1891     2351441 : static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type)
    1892             : {
    1893             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R, 1, 0);
    1894     2351441 : }
    1895             : 
    1896       53044 : static zend_never_inline void zend_fetch_dimension_address_read_R_slow(zval *result, zval *container, zval *dim)
    1897             : {
    1898             :         zend_fetch_dimension_address_read(result, container, dim, IS_CV, BP_VAR_R, 1, 1);
    1899       53044 : }
    1900             : 
    1901         120 : static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type)
    1902             : {
    1903             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1, 0);
    1904         120 : }
    1905             : 
    1906      207029 : static zend_never_inline void zend_fetch_dimension_address_read_LIST(zval *result, zval *container, zval *dim)
    1907             : {
    1908             :         zend_fetch_dimension_address_read(result, container, dim, IS_TMP_VAR, BP_VAR_R, 0, 0);
    1909      207029 : }
    1910             : 
    1911           9 : ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim)
    1912             : {
    1913           9 :         zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR);
    1914           9 : }
    1915             : 
    1916          33 : ZEND_API void zend_fetch_dimension_by_zval_is(zval *result, zval *container, zval *dim, int dim_type)
    1917             : {
    1918             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS, 1, 0);
    1919          33 : }
    1920             : 
    1921             : 
    1922             : static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type)
    1923             : {
    1924      463803 :     if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
    1925             :                 do {
    1926          89 :                         if (Z_ISREF_P(container)) {
    1927          44 :                                 container = Z_REFVAL_P(container);
    1928          44 :                                 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1929             :                                         break;
    1930             :                                 }
    1931             :                         }
    1932             : 
    1933             :                         /* this should modify object only if it's empty */
    1934         103 :                         if (type != BP_VAR_UNSET &&
    1935           3 :                             EXPECTED(Z_TYPE_P(container) <= IS_FALSE ||
    1936             :                               (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0))) {
    1937             :                                 zval_ptr_dtor_nogc(container);
    1938          38 :                                 object_init(container);
    1939             :                         } else {
    1940           9 :                                 if (container_op_type != IS_VAR || EXPECTED(!Z_ISERROR_P(container))) {
    1941           7 :                                         zend_error(E_WARNING, "Attempt to modify property of non-object");
    1942             :                                 }
    1943           8 :                                 ZVAL_ERROR(result);
    1944             :                                 return;
    1945             :                         }
    1946             :                 } while (0);
    1947             :         }
    1948      751798 :         if (prop_op_type == IS_CONST &&
    1949      375890 :             EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) {
    1950      375429 :                 uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
    1951      375429 :                 zend_object *zobj = Z_OBJ_P(container);
    1952             :                 zval *retval;
    1953             : 
    1954      375429 :                 if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) {
    1955      375219 :                         retval = OBJ_PROP(zobj, prop_offset);
    1956      375219 :                         if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
    1957      375219 :                                 ZVAL_INDIRECT(result, retval);
    1958             :                                 return;
    1959             :                         }
    1960         210 :                 } else if (EXPECTED(zobj->properties != NULL)) {
    1961         204 :                         if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) {
    1962           2 :                                 if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) {
    1963           2 :                                         GC_REFCOUNT(zobj->properties)--;
    1964             :                                 }
    1965           2 :                                 zobj->properties = zend_array_dup(zobj->properties);
    1966             :                         }
    1967         204 :                         retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
    1968         204 :                         if (EXPECTED(retval)) {
    1969           5 :                                 ZVAL_INDIRECT(result, retval);
    1970             :                                 return;
    1971             :                         }
    1972             :                 }
    1973             :         }
    1974         684 :         if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
    1975         684 :                 zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot);
    1976         684 :                 if (NULL == ptr) {
    1977          60 :                         if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
    1978             : use_read_property:
    1979          60 :                                 ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result);
    1980          60 :                                 if (ptr != result) {
    1981           2 :                                         ZVAL_INDIRECT(result, ptr);
    1982          66 :                                 } else if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) {
    1983           1 :                                         ZVAL_UNREF(ptr);
    1984             :                                 }
    1985             :                         } else {
    1986           0 :                                 zend_throw_error(NULL, "Cannot access undefined property for object with overloaded property access");
    1987           0 :                                 ZVAL_ERROR(result);
    1988             :                         }
    1989             :                 } else {
    1990         624 :                         ZVAL_INDIRECT(result, ptr);
    1991             :                 }
    1992           0 :         } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
    1993             :                 goto use_read_property; 
    1994             :         } else {
    1995           0 :                 zend_error(E_WARNING, "This object doesn't support property references");
    1996           0 :                 ZVAL_ERROR(result);
    1997             :         }
    1998             : }
    1999             : 
    2000             : #if ZEND_INTENSIVE_DEBUGGING
    2001             : 
    2002             : #define CHECK_SYMBOL_TABLES()                                                                                                   \
    2003             :         zend_hash_apply(&EG(symbol_table), zend_check_symbol);                      \
    2004             :         if (&EG(symbol_table)!=EX(symbol_table)) {                                                  \
    2005             :                 zend_hash_apply(EX(symbol_table), zend_check_symbol);   \
    2006             :         }
    2007             : 
    2008             : static int zend_check_symbol(zval *pz)
    2009             : {
    2010             :         if (Z_TYPE_P(pz) == IS_INDIRECT) {
    2011             :                 pz = Z_INDIRECT_P(pz);
    2012             :         }
    2013             :         if (Z_TYPE_P(pz) > 10) {
    2014             :                 fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
    2015             : /* See http://support.microsoft.com/kb/190351 */
    2016             : #ifdef ZEND_WIN32
    2017             :                 fflush(stderr);
    2018             : #endif
    2019             :         } else if (Z_TYPE_P(pz) == IS_ARRAY) {
    2020             :                 zend_hash_apply(Z_ARRVAL_P(pz), zend_check_symbol);
    2021             :         } else if (Z_TYPE_P(pz) == IS_OBJECT) {
    2022             :                 /* OBJ-TBI - doesn't support new object model! */
    2023             :                 zend_hash_apply(Z_OBJPROP_P(pz), zend_check_symbol);
    2024             :         }
    2025             : 
    2026             :         return 0;
    2027             : }
    2028             : 
    2029             : 
    2030             : #else
    2031             : #define CHECK_SYMBOL_TABLES()
    2032             : #endif
    2033             : 
    2034           0 : ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value)
    2035             : {
    2036           0 :         execute_data->func->internal_function.handler(execute_data, return_value);
    2037           0 : }
    2038             : 
    2039         445 : ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
    2040             : {
    2041         445 :         if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
    2042           4 :                 zend_array_destroy(symbol_table);
    2043             :         } else {
    2044             :                 /* clean before putting into the cache, since clean
    2045             :                    could call dtors, which could use cached hash */
    2046         441 :                 zend_symtable_clean(symbol_table);
    2047         441 :                 *(++EG(symtable_cache_ptr)) = symbol_table;
    2048             :         }
    2049         445 : }
    2050             : /* }}} */
    2051             : 
    2052             : static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
    2053             : {
    2054     4989085 :         zval *cv = EX_VAR_NUM(0);
    2055     4989085 :         zval *end = cv + EX(func)->op_array.last_var;
    2056    29134729 :         while (EXPECTED(cv != end)) {
    2057    24145644 :                 if (Z_REFCOUNTED_P(cv)) {
    2058    15201977 :                         if (!Z_DELREF_P(cv)) {
    2059     6553161 :                                 zend_refcounted *r = Z_COUNTED_P(cv);
    2060     6553161 :                                 ZVAL_NULL(cv);
    2061     6553161 :                                 zval_dtor_func(r);
    2062             :                         } else {
    2063             :                                 GC_ZVAL_CHECK_POSSIBLE_ROOT(cv);
    2064             :                         }
    2065             :                 }
    2066    24145644 :                 cv++;
    2067             :         }
    2068             : }
    2069             : /* }}} */
    2070             : 
    2071       50455 : void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
    2072             : {
    2073             :         i_free_compiled_variables(execute_data);
    2074       50455 : }
    2075             : /* }}} */
    2076             : 
    2077             : #define ZEND_VM_INTERRUPT_CHECK() do { \
    2078             :                 if (UNEXPECTED(EG(vm_interrupt))) { \
    2079             :                         ZEND_VM_INTERRUPT(); \
    2080             :                 } \
    2081             :         } while (0)
    2082             : 
    2083             : #define ZEND_VM_LOOP_INTERRUPT_CHECK() do { \
    2084             :                 if (UNEXPECTED(EG(vm_interrupt))) { \
    2085             :                         ZEND_VM_LOOP_INTERRUPT(); \
    2086             :                 } \
    2087             :         } while (0)
    2088             : 
    2089             : /*
    2090             :  * Stack Frame Layout (the whole stack frame is allocated at once)
    2091             :  * ==================
    2092             :  *
    2093             :  *                             +========================================+
    2094             :  * EG(current_execute_data) -> | zend_execute_data                      |
    2095             :  *                             +----------------------------------------+
    2096             :  *     EX_CV_NUM(0) ---------> | VAR[0] = ARG[1]                        |
    2097             :  *                             | ...                                    |
    2098             :  *                             | VAR[op_array->num_args-1] = ARG[N]     |
    2099             :  *                             | ...                                    |
    2100             :  *                             | VAR[op_array->last_var-1]              |
    2101             :  *                             | VAR[op_array->last_var] = TMP[0]       |
    2102             :  *                             | ...                                    |
    2103             :  *                             | VAR[op_array->last_var+op_array->T-1]  |
    2104             :  *                             | ARG[N+1] (extra_args)                  |
    2105             :  *                             | ...                                    |
    2106             :  *                             +----------------------------------------+
    2107             :  */
    2108             : 
    2109             : static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    2110             : {
    2111             :         uint32_t first_extra_arg, num_args;
    2112             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    2113             : 
    2114     4416075 :         EX(opline) = op_array->opcodes;
    2115     4416075 :         EX(call) = NULL;
    2116     4416075 :         EX(return_value) = return_value;
    2117             : 
    2118             :         /* Handle arguments */
    2119     4416075 :         first_extra_arg = op_array->num_args;
    2120     4416075 :         num_args = EX_NUM_ARGS();
    2121     4416075 :         if (UNEXPECTED(num_args > first_extra_arg)) {
    2122         493 :                 if (EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) {
    2123             :                         zval *end, *src, *dst;
    2124         155 :                         uint32_t type_flags = 0;
    2125             : 
    2126         155 :                         if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    2127             :                                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    2128         151 :                                 EX(opline) += first_extra_arg;
    2129             :                         }
    2130             : 
    2131             :                         /* move extra args into separate array after all CV and TMP vars */
    2132         155 :                         end = EX_VAR_NUM(first_extra_arg - 1);
    2133         155 :                         src = end + (num_args - first_extra_arg);
    2134         155 :                         dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    2135         155 :                         if (EXPECTED(src != dst)) {
    2136             :                                 do {
    2137       86785 :                                         type_flags |= Z_TYPE_INFO_P(src);
    2138       86785 :                                         ZVAL_COPY_VALUE(dst, src);
    2139       86785 :                                         ZVAL_UNDEF(src);
    2140       86785 :                                         src--;
    2141       86785 :                                         dst--;
    2142       86785 :                                 } while (src != end);
    2143             :                         } else {
    2144             :                                 do {
    2145       82799 :                                         type_flags |= Z_TYPE_INFO_P(src);
    2146       82799 :                                         src--;
    2147       82799 :                                 } while (src != end);
    2148             :                         }
    2149         155 :                         ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
    2150             :                 }
    2151     4415582 :         } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    2152             :                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    2153     4327247 :                 EX(opline) += num_args;
    2154             :         }
    2155             : 
    2156             :         /* Initialize CV variables (skip arguments) */
    2157     4416075 :         if (EXPECTED((int)num_args < op_array->last_var)) {
    2158     1629879 :                 zval *var = EX_VAR_NUM(num_args);
    2159     1629879 :                 zval *end = EX_VAR_NUM(op_array->last_var);
    2160             : 
    2161             :                 do {
    2162     9939509 :                         ZVAL_UNDEF(var);
    2163     9939509 :                         var++;
    2164     9939509 :                 } while (var != end);
    2165             :         }
    2166             : 
    2167     4416075 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    2168     4416075 :         EX_LOAD_LITERALS(op_array);
    2169             : 
    2170     4416075 :         EG(current_execute_data) = execute_data;
    2171             : }
    2172             : /* }}} */
    2173             : 
    2174       10026 : static zend_never_inline void ZEND_FASTCALL init_func_run_time_cache(zend_op_array *op_array) /* {{{ */
    2175             : {
    2176             :         ZEND_ASSERT(op_array->run_time_cache == NULL);
    2177       20052 :         op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
    2178       10026 :         memset(op_array->run_time_cache, 0, op_array->cache_size);
    2179       10026 : }
    2180             : /* }}} */
    2181             : 
    2182             : static zend_always_inline void i_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    2183             : {
    2184             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    2185             : 
    2186       11158 :         EX(opline) = op_array->opcodes;
    2187       11158 :         EX(call) = NULL;
    2188       11158 :         EX(return_value) = return_value;
    2189             : 
    2190       11158 :         zend_attach_symbol_table(execute_data);
    2191             : 
    2192       11158 :         if (!op_array->run_time_cache) {
    2193       11158 :                 op_array->run_time_cache = emalloc(op_array->cache_size);
    2194       11158 :                 memset(op_array->run_time_cache, 0, op_array->cache_size);
    2195             :         }
    2196       11158 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    2197       11158 :         EX_LOAD_LITERALS(op_array);
    2198             : 
    2199       11158 :         EG(current_execute_data) = execute_data;
    2200             : }
    2201             : /* }}} */
    2202             : 
    2203             : static zend_always_inline void i_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    2204             : {
    2205             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    2206             : 
    2207      600474 :         EX(opline) = op_array->opcodes;
    2208      600474 :         EX(call) = NULL;
    2209      600474 :         EX(return_value) = return_value;
    2210             : 
    2211      600474 :         if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) {
    2212       23694 :                 zend_attach_symbol_table(execute_data);
    2213             :         } else {
    2214             :                 uint32_t first_extra_arg, num_args;
    2215             : 
    2216             :                 /* Handle arguments */
    2217      576780 :                 first_extra_arg = op_array->num_args;
    2218      576780 :                 num_args = EX_NUM_ARGS();
    2219      576780 :                 if (UNEXPECTED(num_args > first_extra_arg)) {
    2220         815 :                         if (EXPECTED(!(op_array->fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE))) {
    2221             :                                 zval *end, *src, *dst;
    2222         813 :                                 uint32_t type_flags = 0;
    2223             : 
    2224         813 :                                 if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    2225             :                                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    2226         807 :                                         EX(opline) += first_extra_arg;
    2227             :                                 }
    2228             : 
    2229             :                                 /* move extra args into separate array after all CV and TMP vars */
    2230         813 :                                 end = EX_VAR_NUM(first_extra_arg - 1);
    2231         813 :                                 src = end + (num_args - first_extra_arg);
    2232         813 :                                 dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    2233         813 :                                 if (EXPECTED(src != dst)) {
    2234             :                                         do {
    2235         843 :                                                 type_flags |= Z_TYPE_INFO_P(src);
    2236         843 :                                                 ZVAL_COPY_VALUE(dst, src);
    2237         843 :                                                 ZVAL_UNDEF(src);
    2238         843 :                                                 src--;
    2239         843 :                                                 dst--;
    2240         843 :                                         } while (src != end);
    2241             :                                 } else {
    2242             :                                         do {
    2243         757 :                                                 type_flags |= Z_TYPE_INFO_P(src);
    2244         757 :                                                 src--;
    2245         757 :                                         } while (src != end);
    2246             :                                 }
    2247         813 :                                 ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
    2248             :                         }
    2249      575965 :                 } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    2250             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    2251      575951 :                         EX(opline) += num_args;
    2252             :                 }
    2253             : 
    2254             :                 /* Initialize CV variables (skip arguments) */
    2255      576780 :                 if (EXPECTED((int)num_args < op_array->last_var)) {
    2256      229580 :                         zval *var = EX_VAR_NUM(num_args);
    2257      229580 :                         zval *end = EX_VAR_NUM(op_array->last_var);
    2258             : 
    2259             :                         do {
    2260      663709 :                                 ZVAL_UNDEF(var);
    2261      663709 :                                 var++;
    2262      663709 :                         } while (var != end);
    2263             :                 }
    2264             :         }
    2265             : 
    2266      600474 :         if (!op_array->run_time_cache) {
    2267       26726 :                 if (op_array->function_name) {
    2268        6064 :                         op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
    2269             :                 } else {
    2270       23694 :                         op_array->run_time_cache = emalloc(op_array->cache_size);
    2271             :                 }
    2272       26726 :                 memset(op_array->run_time_cache, 0, op_array->cache_size);
    2273             :         }
    2274      600474 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    2275      600474 :         EX_LOAD_LITERALS(op_array);
    2276             : 
    2277      600474 :         EG(current_execute_data) = execute_data;
    2278             : }
    2279             : /* }}} */
    2280             : 
    2281      576780 : ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    2282             : {
    2283      576780 :         EX(prev_execute_data) = EG(current_execute_data);
    2284             :         i_init_execute_data(execute_data, op_array, return_value);
    2285      576780 : }
    2286             : /* }}} */
    2287             : 
    2288             : static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(const zend_op *opline, zend_execute_data *call) /* {{{ */
    2289             : {
    2290     2353668 :         uint32_t arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK;
    2291             : 
    2292     2353668 :         if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) {
    2293     2351671 :                 return QUICK_ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num);
    2294             :         }
    2295        3994 :         return ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num);
    2296             : }
    2297             : /* }}} */
    2298             : 
    2299          10 : static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
    2300             : {
    2301             :         zend_execute_data *new_call;
    2302          10 :         int used_stack = (EG(vm_stack_top) - (zval*)call) + additional_args;
    2303             : 
    2304             :         /* copy call frame into new stack segment */
    2305          10 :         new_call = zend_vm_stack_extend(used_stack * sizeof(zval));
    2306          10 :         *new_call = *call;
    2307          10 :         ZEND_ADD_CALL_FLAG(new_call, ZEND_CALL_ALLOCATED);
    2308             : 
    2309          10 :         if (passed_args) {
    2310           4 :                 zval *src = ZEND_CALL_ARG(call, 1);
    2311           4 :                 zval *dst = ZEND_CALL_ARG(new_call, 1);
    2312             :                 do {
    2313       59114 :                         ZVAL_COPY_VALUE(dst, src);
    2314       59114 :                         passed_args--;
    2315       59114 :                         src++;
    2316       59114 :                         dst++;
    2317       59114 :                 } while (passed_args);
    2318             :         }
    2319             : 
    2320             :         /* delete old call_frame from previous stack segment */
    2321          10 :         EG(vm_stack)->prev->top = (zval*)call;
    2322             : 
    2323             :         /* delete previous stack segment if it becames empty */
    2324          10 :         if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMENTS(EG(vm_stack)->prev))) {
    2325           2 :                 zend_vm_stack r = EG(vm_stack)->prev;
    2326             : 
    2327           2 :                 EG(vm_stack)->prev = r->prev;
    2328           2 :                 efree(r);
    2329             :         }
    2330             : 
    2331          10 :         return new_call;
    2332             : }
    2333             : /* }}} */
    2334             : 
    2335             : static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data **call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
    2336             : {
    2337       17223 :         if (EXPECTED((uint32_t)(EG(vm_stack_end) - EG(vm_stack_top)) > additional_args)) {
    2338       17213 :                 EG(vm_stack_top) += additional_args;
    2339             :         } else {
    2340          10 :                 *call = zend_vm_stack_copy_call_frame(*call, passed_args, additional_args);
    2341             :         }
    2342             : }
    2343             : /* }}} */
    2344             : 
    2345             : static zend_always_inline zend_generator *zend_get_running_generator(zend_execute_data *execute_data) /* {{{ */
    2346             : {
    2347             :         /* The generator object is stored in EX(return_value) */
    2348     2451588 :         zend_generator *generator = (zend_generator *) EX(return_value);
    2349             :         /* However control may currently be delegated to another generator.
    2350             :          * That's the one we're interested in. */
    2351     2451588 :         return generator;
    2352             : }
    2353             : /* }}} */
    2354             : 
    2355        4151 : static void cleanup_unfinished_calls(zend_execute_data *execute_data, uint32_t op_num) /* {{{ */
    2356             : {
    2357        4151 :         if (UNEXPECTED(EX(call))) {
    2358        1083 :                 zend_execute_data *call = EX(call);
    2359        1083 :                 zend_op *opline = EX(func)->op_array.opcodes + op_num;
    2360             :                 int level;
    2361             :                 int do_exit;
    2362             :                 
    2363        1083 :                 if (UNEXPECTED(opline->opcode == ZEND_INIT_FCALL ||
    2364             :                         opline->opcode == ZEND_INIT_FCALL_BY_NAME ||
    2365             :                         opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME ||
    2366             :                         opline->opcode == ZEND_INIT_DYNAMIC_CALL ||
    2367             :                         opline->opcode == ZEND_INIT_USER_CALL ||
    2368             :                         opline->opcode == ZEND_INIT_METHOD_CALL ||
    2369             :                         opline->opcode == ZEND_INIT_STATIC_METHOD_CALL ||
    2370             :                         opline->opcode == ZEND_NEW)) {
    2371             :                         ZEND_ASSERT(op_num);
    2372          25 :                         opline--;
    2373             :                 }
    2374             : 
    2375             :                 do {
    2376             :                         /* If the exception was thrown during a function call there might be
    2377             :                          * arguments pushed to the stack that have to be dtor'ed. */
    2378             : 
    2379             :                         /* find the number of actually passed arguments */
    2380        1106 :                         level = 0;
    2381        1106 :                         do_exit = 0;
    2382             :                         do {
    2383        3904 :                                 switch (opline->opcode) {
    2384             :                                         case ZEND_DO_FCALL:
    2385             :                                         case ZEND_DO_ICALL:
    2386             :                                         case ZEND_DO_UCALL:
    2387             :                                         case ZEND_DO_FCALL_BY_NAME:
    2388         737 :                                                 level++;
    2389         737 :                                                 break;
    2390             :                                         case ZEND_INIT_FCALL:
    2391             :                                         case ZEND_INIT_FCALL_BY_NAME:
    2392             :                                         case ZEND_INIT_NS_FCALL_BY_NAME:
    2393             :                                         case ZEND_INIT_DYNAMIC_CALL:
    2394             :                                         case ZEND_INIT_USER_CALL:
    2395             :                                         case ZEND_INIT_METHOD_CALL:
    2396             :                                         case ZEND_INIT_STATIC_METHOD_CALL:
    2397             :                                         case ZEND_NEW:
    2398        1820 :                                                 if (level == 0) {
    2399        1083 :                                                         ZEND_CALL_NUM_ARGS(call) = 0;
    2400        1083 :                                                         do_exit = 1;
    2401             :                                                 }
    2402        1820 :                                                 level--;
    2403        1820 :                                                 break;
    2404             :                                         case ZEND_SEND_VAL:
    2405             :                                         case ZEND_SEND_VAL_EX:
    2406             :                                         case ZEND_SEND_VAR:
    2407             :                                         case ZEND_SEND_VAR_EX:
    2408             :                                         case ZEND_SEND_REF:
    2409             :                                         case ZEND_SEND_VAR_NO_REF:
    2410             :                                         case ZEND_SEND_VAR_NO_REF_EX:
    2411             :                                         case ZEND_SEND_USER:
    2412         924 :                                                 if (level == 0) {
    2413          18 :                                                         ZEND_CALL_NUM_ARGS(call) = opline->op2.num;
    2414          18 :                                                         do_exit = 1;
    2415             :                                                 }
    2416         924 :                                                 break;
    2417             :                                         case ZEND_SEND_ARRAY:
    2418             :                                         case ZEND_SEND_UNPACK:
    2419           5 :                                                 if (level == 0) {
    2420           5 :                                                         do_exit = 1;
    2421             :                                                 }
    2422             :                                                 break;
    2423             :                                 }
    2424        3904 :                                 if (!do_exit) {
    2425        2798 :                                         opline--;
    2426             :                                 }
    2427        3904 :                         } while (!do_exit);
    2428        1106 :                         if (call->prev_execute_data) {
    2429             :                                 /* skip current call region */
    2430          23 :                                 level = 0;
    2431          23 :                                 do_exit = 0;
    2432             :                                 do {
    2433          52 :                                         switch (opline->opcode) {
    2434             :                                                 case ZEND_DO_FCALL:
    2435             :                                                 case ZEND_DO_ICALL:
    2436             :                                                 case ZEND_DO_UCALL:
    2437             :                                                 case ZEND_DO_FCALL_BY_NAME:
    2438           0 :                                                         level++;
    2439           0 :                                                         break;
    2440             :                                                 case ZEND_INIT_FCALL:
    2441             :                                                 case ZEND_INIT_FCALL_BY_NAME:
    2442             :                                                 case ZEND_INIT_NS_FCALL_BY_NAME:
    2443             :                                                 case ZEND_INIT_DYNAMIC_CALL:
    2444             :                                                 case ZEND_INIT_USER_CALL:
    2445             :                                                 case ZEND_INIT_METHOD_CALL:
    2446             :                                                 case ZEND_INIT_STATIC_METHOD_CALL:
    2447             :                                                 case ZEND_NEW:
    2448          23 :                                                         if (level == 0) {
    2449          23 :                                                                 do_exit = 1;
    2450             :                                                         }
    2451          23 :                                                         level--;
    2452             :                                                         break;
    2453             :                                         }
    2454          52 :                                         opline--;
    2455          52 :                                 } while (!do_exit);
    2456             :                         }
    2457             : 
    2458        1106 :                         zend_vm_stack_free_args(EX(call));
    2459             : 
    2460        1106 :                         if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) {
    2461          14 :                                 if (ZEND_CALL_INFO(call) & ZEND_CALL_CTOR) {
    2462           5 :                                         GC_REFCOUNT(Z_OBJ(call->This))--;
    2463           5 :                                         if (GC_REFCOUNT(Z_OBJ(call->This)) == 1) {
    2464           5 :                                                 zend_object_store_ctor_failed(Z_OBJ(call->This));
    2465             :                                         }
    2466             :                                 }
    2467          14 :                                 OBJ_RELEASE(Z_OBJ(call->This));
    2468             :                         }
    2469        1106 :                         if (call->func->common.fn_flags & ZEND_ACC_CLOSURE) {
    2470           4 :                                 zend_object_release((zend_object *) call->func->common.prototype);
    2471        1102 :                         } else if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
    2472           6 :                                 zend_string_release(call->func->common.function_name);
    2473           6 :                                 zend_free_trampoline(call->func);
    2474             :                         }
    2475             : 
    2476        1106 :                         EX(call) = call->prev_execute_data;
    2477             :                         zend_vm_stack_free_call_frame(call);
    2478        1106 :                         call = EX(call);
    2479        1106 :                 } while (call);
    2480             :         }
    2481        4151 : }
    2482             : /* }}} */
    2483             : 
    2484        4187 : static void cleanup_live_vars(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) /* {{{ */
    2485             : {
    2486             :         int i;
    2487             : 
    2488        9562 :         for (i = 0; i < EX(func)->op_array.last_live_range; i++) {
    2489        5852 :                 const zend_live_range *range = &EX(func)->op_array.live_range[i];
    2490        5852 :                 if (range->start > op_num) {
    2491             :                         /* further blocks will not be relevant... */
    2492         477 :                         break;
    2493        5375 :                 } else if (op_num < range->end) {
    2494        1406 :                         if (!catch_op_num || catch_op_num >= range->end) {
    2495         127 :                                 uint32_t kind = range->var & ZEND_LIVE_MASK;
    2496         127 :                                 uint32_t var_num = range->var & ~ZEND_LIVE_MASK;
    2497         127 :                                 zval *var = EX_VAR(var_num);
    2498             : 
    2499         127 :                                 if (kind == ZEND_LIVE_TMPVAR) {
    2500             :                                         zval_ptr_dtor_nogc(var);
    2501          98 :                                 } else if (kind == ZEND_LIVE_LOOP) {
    2502          44 :                                         if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
    2503           0 :                                                 zend_hash_iterator_del(Z_FE_ITER_P(var));
    2504             :                                         }
    2505             :                                         zval_ptr_dtor_nogc(var);
    2506          54 :                                 } else if (kind == ZEND_LIVE_ROPE) {
    2507           6 :                                         zend_string **rope = (zend_string **)var;
    2508           6 :                                         zend_op *last = EX(func)->op_array.opcodes + op_num;
    2509          29 :                                         while ((last->opcode != ZEND_ROPE_ADD && last->opcode != ZEND_ROPE_INIT)
    2510           8 :                                                         || last->result.var != var_num) {
    2511             :                                                 ZEND_ASSERT(last >= EX(func)->op_array.opcodes);
    2512           9 :                                                 last--;
    2513             :                                         }
    2514           6 :                                         if (last->opcode == ZEND_ROPE_INIT) {
    2515           4 :                                                 zend_string_release(*rope);
    2516             :                                         } else {
    2517           2 :                                                 int j = last->extended_value;
    2518             :                                                 do {
    2519           6 :                                                         zend_string_release(rope[j]);
    2520           6 :                                                 } while (j--);
    2521             :                                         }
    2522          48 :                                 } else if (kind == ZEND_LIVE_SILENCE) {
    2523             :                                         /* restore previous error_reporting value */
    2524          48 :                                         if (!EG(error_reporting) && Z_LVAL_P(var) != 0) {
    2525          34 :                                                 EG(error_reporting) = Z_LVAL_P(var);
    2526             :                                         }
    2527             :                                 }
    2528             :                         }
    2529             :                 }
    2530             :         }
    2531        4187 : }
    2532             : /* }}} */
    2533             : 
    2534         296 : void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num) {
    2535         296 :         cleanup_unfinished_calls(execute_data, op_num);
    2536         296 :         cleanup_live_vars(execute_data, op_num, catch_op_num);
    2537         296 : }
    2538             : 
    2539           1 : static void zend_swap_operands(zend_op *op) /* {{{ */
    2540             : {
    2541             :         znode_op     tmp;
    2542             :         zend_uchar   tmp_type;
    2543             : 
    2544           1 :         tmp          = op->op1;
    2545           1 :         tmp_type     = op->op1_type;
    2546           1 :         op->op1      = op->op2;
    2547           1 :         op->op1_type = op->op2_type;
    2548           1 :         op->op2      = tmp;
    2549           1 :         op->op2_type = tmp_type;
    2550           1 : }
    2551             : /* }}} */
    2552             : 
    2553       13429 : static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_string *function, uint32_t num_args) /* {{{ */
    2554             : {
    2555             :         zend_function *fbc;
    2556             :         zval *func;
    2557             :         zend_class_entry *called_scope;
    2558             :         zend_string *lcname;
    2559             :         const char *colon;
    2560             : 
    2561       26900 :         if ((colon = zend_memrchr(ZSTR_VAL(function), ':', ZSTR_LEN(function))) != NULL &&
    2562          17 :                 colon > ZSTR_VAL(function) &&
    2563          15 :                 *(colon-1) == ':'
    2564             :         ) {
    2565             :                 zend_string *mname;
    2566          14 :                 size_t cname_length = colon - ZSTR_VAL(function) - 1;
    2567          14 :                 size_t mname_length = ZSTR_LEN(function) - cname_length - (sizeof("::") - 1);
    2568             : 
    2569          28 :                 lcname = zend_string_init(ZSTR_VAL(function), cname_length, 0);
    2570             : 
    2571          14 :                 called_scope = zend_fetch_class_by_name(lcname, NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
    2572          14 :                 if (UNEXPECTED(called_scope == NULL)) {
    2573             :                         zend_string_release(lcname);
    2574           3 :                         return NULL;
    2575             :                 }
    2576             : 
    2577          22 :                 mname = zend_string_init(ZSTR_VAL(function) + (cname_length + sizeof("::") - 1), mname_length, 0);
    2578             : 
    2579          11 :                 if (called_scope->get_static_method) {
    2580           0 :                         fbc = called_scope->get_static_method(called_scope, mname);
    2581             :                 } else {
    2582          11 :                         fbc = zend_std_get_static_method(called_scope, mname, NULL);
    2583             :                 }
    2584          11 :                 if (UNEXPECTED(fbc == NULL)) {
    2585           1 :                         if (EXPECTED(!EG(exception))) {
    2586           1 :                                 zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(called_scope->name), ZSTR_VAL(mname));
    2587             :                         }
    2588             :                         zend_string_release(lcname);
    2589             :                         zend_string_release(mname);
    2590           1 :                         return NULL;
    2591             :                 }
    2592             : 
    2593             :                 zend_string_release(lcname);
    2594             :                 zend_string_release(mname);
    2595             : 
    2596          10 :                 if (UNEXPECTED(!(fbc->common.fn_flags & ZEND_ACC_STATIC))) {
    2597           1 :                         if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
    2598           2 :                                 zend_error(E_DEPRECATED,
    2599             :                                         "Non-static method %s::%s() should not be called statically",
    2600           2 :                                         ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
    2601           1 :                                 if (UNEXPECTED(EG(exception) != NULL)) {
    2602           0 :                                         return NULL;
    2603             :                                 }
    2604             :                         } else {
    2605           0 :                                 zend_throw_error(
    2606             :                                         zend_ce_error,
    2607             :                                         "Non-static method %s::%s() cannot be called statically",
    2608           0 :                                         ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
    2609           0 :                                 return NULL;
    2610             :                         }
    2611             :                 }
    2612             :         } else {
    2613       13415 :                 if (ZSTR_VAL(function)[0] == '\\') {
    2614           2 :                         lcname = zend_string_alloc(ZSTR_LEN(function) - 1, 0);
    2615           1 :                         zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(function) + 1, ZSTR_LEN(function) - 1);
    2616             :                 } else {
    2617       13414 :                         lcname = zend_string_tolower(function);
    2618             :                 }
    2619       13415 :                 if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) {
    2620           3 :                         zend_throw_error(NULL, "Call to undefined function %s()", ZSTR_VAL(function));
    2621             :                         zend_string_release(lcname);
    2622           3 :                         return NULL;
    2623             :                 }
    2624             :                 zend_string_release(lcname);
    2625             : 
    2626       13412 :                 fbc = Z_FUNC_P(func);
    2627       13412 :                 called_scope = NULL;
    2628             :         }
    2629             : 
    2630       13422 :         if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
    2631          44 :                 init_func_run_time_cache(&fbc->op_array);
    2632             :         }
    2633             : 
    2634       13422 :         return zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC,
    2635             :                 fbc, num_args, called_scope, NULL);
    2636             : }
    2637             : /* }}} */
    2638             : 
    2639         634 : static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval *function, uint32_t num_args) /* {{{ */
    2640             : {
    2641             :         zend_function *fbc;
    2642             :         zend_class_entry *called_scope;
    2643             :         zend_object *object;
    2644         634 :         uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
    2645             : 
    2646        1902 :         if (EXPECTED(Z_OBJ_HANDLER_P(function, get_closure)) &&
    2647         634 :             EXPECTED(Z_OBJ_HANDLER_P(function, get_closure)(function, &called_scope, &fbc, &object) == SUCCESS)) {
    2648             : 
    2649         634 :                 if (fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
    2650             :                         /* Delay closure destruction until its invocation */
    2651             :                         ZEND_ASSERT(GC_TYPE((zend_object*)fbc->common.prototype) == IS_OBJECT);
    2652         623 :                         GC_REFCOUNT((zend_object*)fbc->common.prototype)++;
    2653         623 :                         call_info |= ZEND_CALL_CLOSURE;
    2654          11 :                 } else if (object) {
    2655          10 :                         call_info |= ZEND_CALL_RELEASE_THIS;
    2656          10 :                         GC_REFCOUNT(object)++; /* For $this pointer */
    2657             :                 }
    2658             :         } else {
    2659           0 :                 zend_throw_error(NULL, "Function name must be a string");
    2660           0 :                 return NULL;
    2661             :         }
    2662             : 
    2663         634 :         if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
    2664           8 :                 init_func_run_time_cache(&fbc->op_array);
    2665             :         }
    2666             : 
    2667        1268 :         return zend_vm_stack_push_call_frame(call_info,
    2668             :                 fbc, num_args, called_scope, object);
    2669             : }
    2670             : /* }}} */
    2671             : 
    2672          32 : static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_array *function, uint32_t num_args) /* {{{ */
    2673             : {
    2674             :         zend_function *fbc;
    2675             :         zend_class_entry *called_scope;
    2676             :         zend_object *object;
    2677          32 :         uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC;
    2678             : 
    2679          32 :         if (zend_hash_num_elements(function) == 2) {
    2680             :                 zval *obj;
    2681             :                 zval *method;
    2682          32 :                 obj = zend_hash_index_find(function, 0);
    2683          32 :                 method = zend_hash_index_find(function, 1);
    2684             : 
    2685          32 :                 if (UNEXPECTED(!obj) || UNEXPECTED(!method)) {
    2686           1 :                         zend_throw_error(NULL, "Array callback has to contain indices 0 and 1");
    2687           1 :                         return NULL;
    2688             :                 }
    2689             : 
    2690          31 :                 ZVAL_DEREF(obj);
    2691          43 :                 if (UNEXPECTED(Z_TYPE_P(obj) != IS_STRING) && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
    2692           0 :                         zend_throw_error(NULL, "First array member is not a valid class name or object");
    2693           0 :                         return NULL;
    2694             :                 }
    2695             : 
    2696          31 :                 ZVAL_DEREF(method);
    2697          31 :                 if (UNEXPECTED(Z_TYPE_P(method) != IS_STRING)) {
    2698           0 :                         zend_throw_error(NULL, "Second array member is not a valid method");
    2699           0 :                         return NULL;
    2700             :                 }
    2701             : 
    2702          31 :                 if (Z_TYPE_P(obj) == IS_STRING) {
    2703          19 :                         object = NULL;
    2704          19 :                         called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION);
    2705          19 :                         if (UNEXPECTED(called_scope == NULL)) {
    2706           4 :                                 return NULL;
    2707             :                         }
    2708             : 
    2709          15 :                         if (called_scope->get_static_method) {
    2710           0 :                                 fbc = called_scope->get_static_method(called_scope, Z_STR_P(method));
    2711             :                         } else {
    2712          15 :                                 fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL);
    2713             :                         }
    2714          15 :                         if (UNEXPECTED(fbc == NULL)) {
    2715           1 :                                 if (EXPECTED(!EG(exception))) {
    2716           1 :                                         zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(called_scope->name), Z_STRVAL_P(method));
    2717             :                                 }
    2718           1 :                                 return NULL;
    2719             :                         }
    2720          14 :                         if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) {
    2721           2 :                                 if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
    2722           4 :                                         zend_error(E_DEPRECATED,
    2723             :                                                 "Non-static method %s::%s() should not be called statically",
    2724           4 :                                                 ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
    2725           2 :                                         if (UNEXPECTED(EG(exception) != NULL)) {
    2726           0 :                                                 return NULL;
    2727             :                                         }
    2728             :                                 } else {
    2729           0 :                                         zend_throw_error(
    2730             :                                                 zend_ce_error,
    2731             :                                                 "Non-static method %s::%s() cannot be called statically",
    2732           0 :                                                 ZSTR_VAL(fbc->common.scope->name), ZSTR_VAL(fbc->common.function_name));
    2733           0 :                                         return NULL;
    2734             :                                 }
    2735             :                         }
    2736             :                 } else {
    2737          12 :                         called_scope = Z_OBJCE_P(obj);
    2738          12 :                         object = Z_OBJ_P(obj);
    2739             : 
    2740          12 :                         fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL);
    2741          12 :                         if (UNEXPECTED(fbc == NULL)) {
    2742           0 :                                 if (EXPECTED(!EG(exception))) {
    2743           0 :                                         zend_throw_error(NULL, "Call to undefined method %s::%s()", ZSTR_VAL(object->ce->name), Z_STRVAL_P(method));
    2744             :                                 }
    2745           0 :                                 return NULL;
    2746             :                         }
    2747             : 
    2748          12 :                         if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
    2749           3 :                                 object = NULL;
    2750             :                         } else {
    2751           9 :                                 call_info |= ZEND_CALL_RELEASE_THIS;
    2752           9 :                                 GC_REFCOUNT(object)++; /* For $this pointer */
    2753             :                         }
    2754             :                 }
    2755             :         } else {
    2756           0 :                 zend_throw_error(NULL, "Function name must be a string");
    2757           0 :                 return NULL;
    2758             :         }
    2759             : 
    2760          26 :         if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
    2761          10 :                 init_func_run_time_cache(&fbc->op_array);
    2762             :         }
    2763             : 
    2764          52 :         return zend_vm_stack_push_call_frame(call_info,
    2765             :                 fbc, num_args, called_scope, object);
    2766             : }
    2767             : /* }}} */
    2768             : 
    2769             : #define ZEND_FAKE_OP_ARRAY ((zend_op_array*)(zend_intptr_t)-1)
    2770             : 
    2771       11778 : static zend_never_inline zend_op_array* ZEND_FASTCALL zend_include_or_eval(zval *inc_filename, int type) /* {{{ */
    2772             : {
    2773       11778 :         zend_op_array *new_op_array = NULL;
    2774             :         zval tmp_inc_filename;
    2775             : 
    2776       11778 :         ZVAL_UNDEF(&tmp_inc_filename);
    2777       11778 :         if (Z_TYPE_P(inc_filename) != IS_STRING) {
    2778           2 :                 ZVAL_STR(&tmp_inc_filename, zval_get_string(inc_filename));
    2779           1 :                 inc_filename = &tmp_inc_filename;
    2780             :         }
    2781             : 
    2782       11778 :         if (type != ZEND_EVAL && strlen(Z_STRVAL_P(inc_filename)) != Z_STRLEN_P(inc_filename)) {
    2783           0 :                 if (type == ZEND_INCLUDE_ONCE || type == ZEND_INCLUDE) {
    2784           0 :                         zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
    2785             :                 } else {
    2786           0 :                         zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
    2787             :                 }
    2788             :         } else {
    2789       11778 :                 switch (type) {
    2790             :                         case ZEND_INCLUDE_ONCE:
    2791             :                         case ZEND_REQUIRE_ONCE: {
    2792             :                                         zend_file_handle file_handle;
    2793             :                                         zend_string *resolved_path;
    2794             : 
    2795        6206 :                                         resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename));
    2796        6206 :                                         if (resolved_path) {
    2797        6202 :                                                 if (zend_hash_exists(&EG(included_files), resolved_path)) {
    2798         569 :                                                         goto already_compiled;
    2799             :                                                 }
    2800             :                                         } else {
    2801           8 :                                                 resolved_path = zend_string_copy(Z_STR_P(inc_filename));
    2802             :                                         }
    2803             : 
    2804        5637 :                                         if (SUCCESS == zend_stream_open(ZSTR_VAL(resolved_path), &file_handle)) {
    2805             : 
    2806        5635 :                                                 if (!file_handle.opened_path) {
    2807           4 :                                                         file_handle.opened_path = zend_string_copy(resolved_path);
    2808             :                                                 }
    2809             : 
    2810        5635 :                                                 if (zend_hash_add_empty_element(&EG(included_files), file_handle.opened_path)) {
    2811        5634 :                                                         zend_op_array *op_array = zend_compile_file(&file_handle, (type==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE));
    2812        5634 :                                                         zend_destroy_file_handle(&file_handle);
    2813             :                                                         zend_string_release(resolved_path);
    2814        5634 :                                                         if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) {
    2815           0 :                                                                 zend_string_release(Z_STR(tmp_inc_filename));
    2816             :                                                         }
    2817        5634 :                                                         return op_array;
    2818             :                                                 } else {
    2819           1 :                                                         zend_file_handle_dtor(&file_handle);
    2820             : already_compiled:
    2821         570 :                                                         new_op_array = ZEND_FAKE_OP_ARRAY;
    2822             :                                                 }
    2823             :                                         } else {
    2824           2 :                                                 if (type == ZEND_INCLUDE_ONCE) {
    2825           0 :                                                         zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, Z_STRVAL_P(inc_filename));
    2826             :                                                 } else {
    2827           2 :                                                         zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, Z_STRVAL_P(inc_filename));
    2828             :                                                 }
    2829             :                                         }
    2830             :                                         zend_string_release(resolved_path);
    2831             :                                 }
    2832         570 :                                 break;
    2833             :                         case ZEND_INCLUDE:
    2834             :                         case ZEND_REQUIRE:
    2835        4540 :                                 new_op_array = compile_filename(type, inc_filename);
    2836        4537 :                                 break;
    2837             :                         case ZEND_EVAL: {
    2838        1032 :                                         char *eval_desc = zend_make_compiled_string_description("eval()'d code");
    2839        1032 :                                         new_op_array = zend_compile_string(inc_filename, eval_desc);
    2840        1030 :                                         efree(eval_desc);
    2841             :                                 }
    2842             :                                 break;
    2843             :                         EMPTY_SWITCH_DEFAULT_CASE()
    2844             :                 }
    2845             :         }
    2846        6137 :         if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) {
    2847           1 :                 zend_string_release(Z_STR(tmp_inc_filename));
    2848             :         }
    2849        6137 :         return new_op_array;
    2850             : }
    2851             : /* }}} */
    2852             : 
    2853           0 : static zend_never_inline int zend_do_fcall_overloaded(zend_function *fbc, zend_execute_data *call, zval *ret) /* {{{ */
    2854             : {
    2855             :         zend_object *object;
    2856             : 
    2857             :         /* Not sure what should be done here if it's a static method */
    2858           0 :         if (UNEXPECTED(Z_TYPE(call->This) != IS_OBJECT)) {
    2859             :                 zend_vm_stack_free_args(call);
    2860           0 :                 if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
    2861           0 :                         zend_string_release(fbc->common.function_name);
    2862             :                 }
    2863           0 :                 efree(fbc);
    2864             :                 zend_vm_stack_free_call_frame(call);
    2865             : 
    2866           0 :                 zend_throw_error(NULL, "Cannot call overloaded function for non-object");
    2867           0 :                 return 0;
    2868             :         }
    2869             : 
    2870           0 :         object = Z_OBJ(call->This);
    2871             : 
    2872           0 :         ZVAL_NULL(ret);
    2873             : 
    2874           0 :         EG(current_execute_data) = call;
    2875           0 :         object->handlers->call_method(fbc->common.function_name, object, call, ret);
    2876           0 :         EG(current_execute_data) = call->prev_execute_data;
    2877             : 
    2878             :         zend_vm_stack_free_args(call);
    2879             : 
    2880           0 :         if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
    2881           0 :                 zend_string_release(fbc->common.function_name);
    2882             :         }
    2883           0 :         efree(fbc);
    2884             : 
    2885           0 :         return 1;
    2886             : }
    2887             : /* }}} */
    2888             : 
    2889             : #ifdef HAVE_GCC_GLOBAL_REGS
    2890             : # if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
    2891             : #  define ZEND_VM_FP_GLOBAL_REG "%esi"
    2892             : #  define ZEND_VM_IP_GLOBAL_REG "%edi"
    2893             : # elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__x86_64__)
    2894             : #  define ZEND_VM_FP_GLOBAL_REG "%r14"
    2895             : #  define ZEND_VM_IP_GLOBAL_REG "%r15"
    2896             : # elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__powerpc64__)
    2897             : #  define ZEND_VM_FP_GLOBAL_REG "r28"
    2898             : #  define ZEND_VM_IP_GLOBAL_REG "r29"
    2899             : # elif defined(__IBMC__) && ZEND_GCC_VERSION >= 4002 && defined(__powerpc64__)
    2900             : #  define ZEND_VM_FP_GLOBAL_REG "r28"
    2901             : #  define ZEND_VM_IP_GLOBAL_REG "r29"
    2902             : # endif
    2903             : #endif
    2904             : 
    2905             : #define ZEND_VM_NEXT_OPCODE_EX(check_exception, skip) \
    2906             :         CHECK_SYMBOL_TABLES() \
    2907             :         if (check_exception) { \
    2908             :                 OPLINE = EX(opline) + (skip); \
    2909             :         } else { \
    2910             :                 OPLINE = opline + (skip); \
    2911             :         } \
    2912             :         ZEND_VM_CONTINUE()
    2913             : 
    2914             : #define ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION() \
    2915             :         ZEND_VM_NEXT_OPCODE_EX(1, 1)
    2916             : 
    2917             : #define ZEND_VM_NEXT_OPCODE() \
    2918             :         ZEND_VM_NEXT_OPCODE_EX(0, 1)
    2919             : 
    2920             : #define ZEND_VM_SET_NEXT_OPCODE(new_op) \
    2921             :         CHECK_SYMBOL_TABLES() \
    2922             :         OPLINE = new_op
    2923             : 
    2924             : #define ZEND_VM_SET_OPCODE(new_op) \
    2925             :         CHECK_SYMBOL_TABLES() \
    2926             :         OPLINE = new_op; \
    2927             :         ZEND_VM_INTERRUPT_CHECK()
    2928             : 
    2929             : #define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
    2930             :         ZEND_VM_SET_OPCODE(ZEND_OFFSET_TO_OPLINE(opline, offset))
    2931             : 
    2932             : #define ZEND_VM_JMP(new_op) \
    2933             :         if (EXPECTED(!EG(exception))) { \
    2934             :                 ZEND_VM_SET_OPCODE(new_op); \
    2935             :         } else { \
    2936             :                 LOAD_OPLINE(); \
    2937             :         } \
    2938             :         ZEND_VM_CONTINUE()
    2939             : 
    2940             : #define ZEND_VM_INC_OPCODE() \
    2941             :         OPLINE++
    2942             : 
    2943             : 
    2944             : #ifndef VM_SMART_OPCODES
    2945             : # define VM_SMART_OPCODES 1
    2946             : #endif
    2947             : 
    2948             : #if VM_SMART_OPCODES
    2949             : # define ZEND_VM_REPEATABLE_OPCODE \
    2950             :         do {
    2951             : # define ZEND_VM_REPEAT_OPCODE(_opcode) \
    2952             :         } while (UNEXPECTED((++opline)->opcode == _opcode)); \
    2953             :         OPLINE = opline; \
    2954             :         ZEND_VM_CONTINUE()
    2955             : # define ZEND_VM_SMART_BRANCH(_result, _check) do { \
    2956             :                 int __result; \
    2957             :                 if (EXPECTED((opline+1)->opcode == ZEND_JMPZ)) { \
    2958             :                         __result = (_result); \
    2959             :                 } else if (EXPECTED((opline+1)->opcode == ZEND_JMPNZ)) { \
    2960             :                         __result = !(_result); \
    2961             :                 } else { \
    2962             :                         break; \
    2963             :                 } \
    2964             :                 if ((_check) && UNEXPECTED(EG(exception))) { \
    2965             :                         HANDLE_EXCEPTION(); \
    2966             :                 } \
    2967             :                 if (__result) { \
    2968             :                         ZEND_VM_SET_NEXT_OPCODE(opline + 2); \
    2969             :                 } else { \
    2970             :                         ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline + 1, (opline+1)->op2)); \
    2971             :                 } \
    2972             :                 ZEND_VM_CONTINUE(); \
    2973             :         } while (0)
    2974             : # define ZEND_VM_SMART_BRANCH_JMPZ(_result, _check) do { \
    2975             :                 if ((_check) && UNEXPECTED(EG(exception))) { \
    2976             :                         HANDLE_EXCEPTION(); \
    2977             :                 } \
    2978             :                 if (_result) { \
    2979             :                         ZEND_VM_SET_NEXT_OPCODE(opline + 2); \
    2980             :                 } else { \
    2981             :                         ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline + 1, (opline+1)->op2)); \
    2982             :                 } \
    2983             :                 ZEND_VM_CONTINUE(); \
    2984             :         } while (0)
    2985             : # define ZEND_VM_SMART_BRANCH_JMPNZ(_result, _check) do { \
    2986             :                 if ((_check) && UNEXPECTED(EG(exception))) { \
    2987             :                         HANDLE_EXCEPTION(); \
    2988             :                 } \
    2989             :                 if (!(_result)) { \
    2990             :                         ZEND_VM_SET_NEXT_OPCODE(opline + 2); \
    2991             :                 } else { \
    2992             :                         ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline + 1, (opline+1)->op2)); \
    2993             :                 } \
    2994             :                 ZEND_VM_CONTINUE(); \
    2995             :         } while (0)
    2996             : #else
    2997             : # define ZEND_VM_REPEATABLE_OPCODE
    2998             : # define ZEND_VM_REPEAT_OPCODE(_opcode)
    2999             : # define ZEND_VM_SMART_BRANCH(_result, _check)
    3000             : # define ZEND_VM_SMART_BRANCH_JMPZ(_result, _check)
    3001             : # define ZEND_VM_SMART_BRANCH_JMPNZ(_result, _check)
    3002             : #endif
    3003             : 
    3004             : #ifdef __GNUC__
    3005             : # define ZEND_VM_GUARD(name) __asm__("#" #name)
    3006             : #else
    3007             : # define ZEND_VM_GUARD(name)
    3008             : #endif
    3009             : 
    3010             : #define GET_OP1_UNDEF_CV(ptr, type) \
    3011             :         _get_zval_cv_lookup_ ## type(ptr, opline->op1.var, execute_data)
    3012             : #define GET_OP2_UNDEF_CV(ptr, type) \
    3013             :         _get_zval_cv_lookup_ ## type(ptr, opline->op2.var, execute_data)
    3014             : 
    3015             : #include "zend_vm_execute.h"
    3016             : 
    3017           0 : ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
    3018             : {
    3019           0 :         if (opcode != ZEND_USER_OPCODE) {
    3020           0 :                 if (handler == NULL) {
    3021             :                         /* restore the original handler */
    3022           0 :                         zend_user_opcodes[opcode] = opcode;
    3023             :                 } else {
    3024           0 :                         zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
    3025             :                 }
    3026           0 :                 zend_user_opcode_handlers[opcode] = handler;
    3027           0 :                 return SUCCESS;
    3028             :         }
    3029           0 :         return FAILURE;
    3030             : }
    3031             : 
    3032           0 : ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
    3033             : {
    3034           0 :         return zend_user_opcode_handlers[opcode];
    3035             : }
    3036             : 
    3037           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)
    3038             : {
    3039           0 :         return get_zval_ptr(op_type, *node, execute_data, should_free, type);
    3040             : }
    3041             : 
    3042           0 : ZEND_API void ZEND_FASTCALL zend_check_internal_arg_type(zend_function *zf, uint32_t arg_num, zval *arg)
    3043             : {
    3044           0 :         zend_verify_internal_arg_type(zf, arg_num, arg);
    3045           0 : }
    3046             : 
    3047           0 : ZEND_API int ZEND_FASTCALL zend_check_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value, void **cache_slot)
    3048             : {
    3049           0 :         return zend_verify_arg_type(zf, arg_num, arg, default_value, cache_slot);
    3050             : }
    3051             : 
    3052             : /*
    3053             :  * Local variables:
    3054             :  * tab-width: 4
    3055             :  * c-basic-offset: 4
    3056             :  * indent-tabs-mode: t
    3057             :  * End:
    3058             :  */

Generated by: LCOV version 1.10

Generated at Tue, 27 Sep 2016 10:25:53 +0000 (27 hours ago)

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