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: 684 779 87.8 %
Date: 2015-01-18 Functions: 30 38 78.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | Zend Engine                                                          |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1998-2015 Zend Technologies Ltd. (http://www.zend.com) |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 2.00 of the Zend license,     |
       8             :    | that is bundled with this package in the file LICENSE, and is        |
       9             :    | available through the world-wide-web at the following url:           |
      10             :    | http://www.zend.com/license/2_00.txt.                                |
      11             :    | If you did not receive a copy of the Zend license and are unable to  |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@zend.com so we can mail you a copy immediately.              |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Andi Gutmans <andi@zend.com>                                |
      16             :    |          Zeev Suraski <zeev@zend.com>                                |
      17             :    +----------------------------------------------------------------------+
      18             : */
      19             : 
      20             : /* $Id$ */
      21             : 
      22             : #define ZEND_INTENSIVE_DEBUGGING 0
      23             : 
      24             : #include <stdio.h>
      25             : #include <signal.h>
      26             : 
      27             : #include "zend.h"
      28             : #include "zend_compile.h"
      29             : #include "zend_execute.h"
      30             : #include "zend_API.h"
      31             : #include "zend_ptr_stack.h"
      32             : #include "zend_constants.h"
      33             : #include "zend_extensions.h"
      34             : #include "zend_ini.h"
      35             : #include "zend_exceptions.h"
      36             : #include "zend_interfaces.h"
      37             : #include "zend_closures.h"
      38             : #include "zend_generators.h"
      39             : #include "zend_vm.h"
      40             : #include "zend_dtrace.h"
      41             : #include "zend_inheritance.h"
      42             : 
      43             : /* Virtual current working directory support */
      44             : #include "zend_virtual_cwd.h"
      45             : 
      46             : #define _CONST_CODE  0
      47             : #define _TMP_CODE    1
      48             : #define _VAR_CODE    2
      49             : #define _UNUSED_CODE 3
      50             : #define _CV_CODE     4
      51             : 
      52             : typedef int (*incdec_t)(zval *);
      53             : 
      54             : #define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type)
      55             : #define get_zval_ptr_deref(op_type, node, ex, should_free, type) _get_zval_ptr_deref(op_type, node, ex, should_free, type)
      56             : #define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
      57             : #define get_zval_ptr_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
      58             : #define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type)
      59             : #define get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type)
      60             : 
      61             : /* Prototypes */
      62             : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array);
      63             : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array);
      64             : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array);
      65             : 
      66             : #define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
      67             : 
      68          71 : static ZEND_FUNCTION(pass)
      69             : {
      70          71 : }
      71             : 
      72             : static const zend_internal_function zend_pass_function = {
      73             :         ZEND_INTERNAL_FUNCTION, /* type              */
      74             :         0,                      /* fn_flags          */
      75             :         NULL,                   /* name              */
      76             :         NULL,                   /* scope             */
      77             :         NULL,                   /* prototype         */
      78             :         0,                      /* num_args          */
      79             :         0,                      /* required_num_args */
      80             :         NULL,                   /* arg_info          */
      81             :         ZEND_FN(pass),          /* handler           */
      82             :         NULL                    /* module            */
      83             : };
      84             : 
      85             : #undef zval_ptr_dtor
      86             : #define zval_ptr_dtor(zv) i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC)
      87             : 
      88             : #define PZVAL_LOCK(z) if (Z_REFCOUNTED_P(z)) Z_ADDREF_P((z))
      89             : #define SELECTIVE_PZVAL_LOCK(pzv, opline)       if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
      90             : 
      91             : #define READY_TO_DESTROY(zv) \
      92             :         (zv && Z_REFCOUNTED_P(zv) && Z_REFCOUNT_P(zv) == 1)
      93             : 
      94             : #define EXTRACT_ZVAL_PTR(zv) do {                                               \
      95             :                 zval *__zv = (zv);                                                              \
      96             :                 if (Z_TYPE_P(__zv) == IS_INDIRECT) {                    \
      97             :                         ZVAL_COPY(__zv, Z_INDIRECT_P(__zv));            \
      98             :                 }                                                                                               \
      99             :         } while (0)
     100             : 
     101             : #define FREE_OP(should_free) \
     102             :         if (should_free) { \
     103             :                 zval_ptr_dtor_nogc(should_free); \
     104             :         }
     105             : 
     106             : #define FREE_OP_VAR_PTR(should_free) \
     107             :         if (should_free) { \
     108             :                 zval_ptr_dtor_nogc(should_free); \
     109             :         }
     110             : 
     111             : /* End of zend_execute_locks.h */
     112             : 
     113             : #define CV_DEF_OF(i) (EX(func)->op_array.vars[i])
     114             : 
     115             : #define CTOR_CALL_BIT    0x1
     116             : #define CTOR_USED_BIT    0x2
     117             : 
     118             : #define IS_CTOR_CALL(ce) (((zend_uintptr_t)(ce)) & CTOR_CALL_BIT)
     119             : #define IS_CTOR_USED(ce) (((zend_uintptr_t)(ce)) & CTOR_USED_BIT)
     120             : 
     121             : #define ENCODE_CTOR(ce, used) \
     122             :         ((zend_class_entry*)(((zend_uintptr_t)(ce)) | CTOR_CALL_BIT | ((used) ? CTOR_USED_BIT : 0)))
     123             : #define DECODE_CTOR(ce) \
     124             :         ((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT)))
     125             : 
     126             : #define ZEND_VM_STACK_PAGE_SLOTS (16 * 1024) /* should be a power of 2 */
     127             : 
     128             : #define ZEND_VM_STACK_PAGE_SIZE  (ZEND_VM_STACK_PAGE_SLOTS * sizeof(zval))
     129             : 
     130             : #define ZEND_VM_STACK_FREE_PAGE_SIZE \
     131             :         ((ZEND_VM_STACK_PAGE_SLOTS - ZEND_VM_STACK_HEADER_SLOTS) * sizeof(zval))
     132             : 
     133             : #define ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size) \
     134             :         (((size) + (ZEND_VM_STACK_FREE_PAGE_SIZE - 1)) & ~ZEND_VM_STACK_PAGE_SIZE)
     135             : 
     136             : static zend_always_inline zend_vm_stack zend_vm_stack_new_page(size_t size, zend_vm_stack prev) {
     137       20736 :         zend_vm_stack page = (zend_vm_stack)emalloc(size);
     138             : 
     139       20736 :         page->top = ZEND_VM_STACK_ELEMETS(page);
     140       20736 :         page->end = (zval*)((char*)page + size);
     141       20736 :         page->prev = prev;
     142       20736 :         return page;
     143             : }
     144             : 
     145       20645 : ZEND_API void zend_vm_stack_init(void)
     146             : {
     147       20645 :         EG(vm_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE, NULL);
     148       20645 :         EG(vm_stack)->top++;
     149       20645 :         EG(vm_stack_top) = EG(vm_stack)->top;
     150       20645 :         EG(vm_stack_end) = EG(vm_stack)->end;
     151       20645 : }
     152             : 
     153       20681 : ZEND_API void zend_vm_stack_destroy(void)
     154             : {
     155       20681 :         zend_vm_stack stack = EG(vm_stack);
     156             : 
     157       62043 :         while (stack != NULL) {
     158       20681 :                 zend_vm_stack p = stack->prev;
     159       20681 :                 efree(stack);
     160       20681 :                 stack = p;
     161             :         }
     162       20681 : }
     163             : 
     164           7 : ZEND_API void* zend_vm_stack_extend(size_t size)
     165             : {
     166             :     zend_vm_stack stack;
     167             :     void *ptr;
     168             : 
     169           7 :     stack = EG(vm_stack);
     170           7 :     stack->top = EG(vm_stack_top);
     171          20 :         EG(vm_stack) = stack = zend_vm_stack_new_page(
     172           7 :                 EXPECTED(size < ZEND_VM_STACK_FREE_PAGE_SIZE) ?
     173           6 :                         ZEND_VM_STACK_PAGE_SIZE : ZEND_VM_STACK_PAGE_ALIGNED_SIZE(size),
     174             :                 stack);
     175           7 :         ptr = stack->top;
     176           7 :         EG(vm_stack_top) = (void*)(((char*)ptr) + size);
     177           7 :         EG(vm_stack_end) = stack->end;
     178           7 :         return ptr;
     179             : }
     180             : 
     181           0 : ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data, uint32_t var)
     182             : {
     183           0 :         return EX_VAR(var);
     184             : }
     185             : 
     186             : static zend_always_inline zval *_get_zval_ptr_tmp(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     187             : {
     188     4716471 :         zval *ret = EX_VAR(var);
     189     4716471 :         *should_free = ret;
     190             : 
     191             :         ZEND_ASSERT(Z_TYPE_P(ret) != IS_REFERENCE);
     192             : 
     193     4716471 :         return ret;
     194             : }
     195             : 
     196             : static zend_always_inline zval *_get_zval_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     197             : {
     198    42040663 :         zval *ret = EX_VAR(var);
     199             : 
     200    42040663 :         *should_free = ret;
     201    42040663 :         return ret;
     202             : }
     203             : 
     204             : static zend_always_inline zval *_get_zval_ptr_var_deref(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     205             : {
     206    11768666 :         zval *ret = EX_VAR(var);
     207             : 
     208    11768666 :         *should_free = ret;
     209    11768666 :         ZVAL_DEREF(ret);
     210    11768666 :         return ret;
     211             : }
     212             : 
     213          10 : static zend_never_inline zval *_get_zval_cv_lookup(zval *ptr, uint32_t var, int type, const zend_execute_data *execute_data)
     214             : {
     215             :         zend_string *cv;
     216             : 
     217          10 :         switch (type) {
     218             :                 case BP_VAR_R:
     219             :                 case BP_VAR_UNSET:
     220          10 :                         cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     221          10 :                         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     222             :                         /* break missing intentionally */
     223             :                 case BP_VAR_IS:
     224          10 :                         ptr = &EG(uninitialized_zval);
     225          10 :                         break;
     226             :                 case BP_VAR_RW:
     227           0 :                         cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     228           0 :                         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     229             :                         /* break missing intentionally */
     230             :                 case BP_VAR_W:
     231           0 :                         ZVAL_NULL(ptr);
     232             :                         break;
     233             :         }
     234          10 :         return ptr;
     235             : }
     236             : 
     237             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_R(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     238             : {
     239         597 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     240             : 
     241         597 :         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     242         597 :         return &EG(uninitialized_zval);
     243             : }
     244             : 
     245             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_UNSET(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     246             : {
     247           0 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     248             : 
     249           0 :         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     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           3 :         zend_string *cv = CV_DEF_OF(EX_VAR_TO_NUM(var));
     256             : 
     257           3 :         ZVAL_NULL(ptr);
     258           3 :         zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
     259           3 :         return ptr;
     260             : }
     261             : 
     262             : static zend_always_inline zval *_get_zval_cv_lookup_BP_VAR_W(zval *ptr, uint32_t var, const zend_execute_data *execute_data)
     263             : {
     264       38330 :         ZVAL_NULL(ptr);
     265       38330 :         return ptr;
     266             : }
     267             : 
     268             : static zend_always_inline zval *_get_zval_ptr_cv(const zend_execute_data *execute_data, uint32_t var, int type)
     269             : {
     270     1073088 :         zval *ret = EX_VAR(var);
     271             : 
     272     1073088 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     273           0 :                 return _get_zval_cv_lookup(ret, var, type, execute_data);
     274             :         }
     275     1073088 :         return ret;
     276             : }
     277             : 
     278             : static zend_always_inline zval *_get_zval_ptr_cv_deref(const zend_execute_data *execute_data, uint32_t var, int type)
     279             : {
     280     2049005 :         zval *ret = EX_VAR(var);
     281             : 
     282     2049005 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     283          10 :                 return _get_zval_cv_lookup(ret, var, type, execute_data);
     284             :         }
     285     2048995 :         ZVAL_DEREF(ret);
     286     2048995 :         return ret;
     287             : }
     288             : 
     289             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, uint32_t var)
     290             : {
     291    49391227 :         zval *ret = EX_VAR(var);
     292             : 
     293    49391227 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     294         587 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data);
     295             :         }
     296    49390640 :         return ret;
     297             : }
     298             : 
     299             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_R(const zend_execute_data *execute_data, uint32_t var)
     300             : {
     301     5084264 :         zval *ret = EX_VAR(var);
     302             : 
     303     5084264 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     304          10 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data);
     305             :         }
     306     5084254 :         ZVAL_DEREF(ret);
     307     5084254 :         return ret;
     308             : }
     309             : 
     310             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var)
     311             : {
     312       21797 :         zval *ret = EX_VAR(var);
     313             : 
     314       21797 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     315           0 :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data);
     316             :         }
     317       21797 :         return ret;
     318             : }
     319             : 
     320             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_UNSET(const zend_execute_data *execute_data, uint32_t var)
     321             : {
     322             :         zval *ret = EX_VAR(var);
     323             : 
     324             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     325             :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data);
     326             :         }
     327             :         ZVAL_DEREF(ret);
     328             :         return ret;
     329             : }
     330             : 
     331             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, uint32_t var)
     332             : {
     333      458461 :         zval *ret = EX_VAR(var);
     334             : 
     335      458461 :         return ret;
     336             : }
     337             : 
     338             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_IS(const zend_execute_data *execute_data, uint32_t var)
     339             : {
     340             :         zval *ret = EX_VAR(var);
     341             : 
     342             :         ZVAL_DEREF(ret);
     343             :         return ret;
     344             : }
     345             : 
     346             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var)
     347             : {
     348    10085632 :         zval *ret = EX_VAR(var);
     349             : 
     350    10085632 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     351           3 :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data);
     352             :         }
     353    10085629 :         return ret;
     354             : }
     355             : 
     356             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var)
     357             : {
     358             :         zval *ret = EX_VAR(var);
     359             : 
     360             :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     361             :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data);
     362             :         }
     363             :         ZVAL_DEREF(ret);
     364             :         return ret;
     365             : }
     366             : 
     367             : static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
     368             : {
     369     3962218 :         zval *ret = EX_VAR(var);
     370             : 
     371     3962218 :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     372       38330 :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data);
     373             :         }
     374     3923888 :         return ret;
     375             : }
     376             : 
     377             : static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
     378             : {
     379    21074317 :         return EX_VAR(var);
     380             : }
     381             : 
     382             : static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
     383             : {
     384             :         zval *ret = EX_VAR(var);
     385             : 
     386             :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     387             :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data);
     388             :         }
     389             :         ZVAL_DEREF(ret);
     390             :         return ret;
     391             : }
     392             : 
     393             : 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)
     394             : {
     395     1074330 :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     396        1157 :                 if (op_type == IS_TMP_VAR) {
     397        2234 :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     398             :                 } else {
     399             :                         ZEND_ASSERT(op_type == IS_VAR);
     400          80 :                         return _get_zval_ptr_var(node.var, execute_data, should_free);
     401             :                 }
     402             :         } else {
     403     1073173 :                 *should_free = NULL;
     404     1073173 :                 if (op_type == IS_CONST) {
     405          85 :                         return EX_CONSTANT(node);
     406             :                 } else {
     407             :                         ZEND_ASSERT(op_type == IS_CV);
     408     2146176 :                         return _get_zval_ptr_cv(execute_data, node.var, type);
     409             :                 }
     410             :         }
     411             : }
     412             : 
     413             : 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)
     414             : {
     415     3032991 :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     416      316436 :                 if (op_type == IS_TMP_VAR) {
     417      214548 :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     418             :                 } else {
     419             :                         ZEND_ASSERT(op_type == IS_VAR);
     420      418324 :                         return _get_zval_ptr_var_deref(node.var, execute_data, should_free);
     421             :                 }
     422             :         } else {
     423     2716555 :                 *should_free = NULL;
     424     2716555 :                 if (op_type == IS_CONST) {
     425      667550 :                         return EX_CONSTANT(node);
     426             :                 } else {
     427             :                         ZEND_ASSERT(op_type == IS_CV);
     428     4098010 :                         return _get_zval_ptr_cv_deref(execute_data, node.var, type);
     429             :                 }
     430             :         }
     431             : }
     432             : 
     433             : static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
     434             : {
     435      699438 :         zval *ret = EX_VAR(var);
     436             : 
     437      699438 :         if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
     438      698253 :                 *should_free = NULL;
     439      698253 :                 ret = Z_INDIRECT_P(ret);
     440             :         } else {
     441        1185 :                 *should_free = ret;
     442        2299 :                 if (Z_REFCOUNTED_P(ret) && Z_REFCOUNT_P(ret) > 1) {
     443        1002 :                         *should_free = NULL;
     444             :                         Z_DELREF_P(ret);
     445             :                 }
     446             :         }
     447      699438 :         return ret;
     448             : }
     449             : 
     450             : 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)
     451             : {
     452             :         if (op_type == IS_CV) {
     453             :                 *should_free = NULL;
     454             :                 return _get_zval_ptr_cv(execute_data, node.var, type);
     455             :         } else /* if (op_type == IS_VAR) */ {
     456             :                 ZEND_ASSERT(op_type == IS_VAR);
     457             :                 return _get_zval_ptr_ptr_var(node.var, execute_data, should_free);
     458             :         }
     459             : }
     460             : 
     461             : static zend_always_inline zval *_get_obj_zval_ptr_unused(zend_execute_data *execute_data)
     462             : {
     463      225665 :         if (EXPECTED(Z_OBJ(EX(This)) != NULL)) {
     464      225661 :                 return &EX(This);
     465             :         } else {
     466           4 :                 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     467             :                 return NULL;
     468             :         }
     469             : }
     470             : 
     471             : 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)
     472             : {
     473             :         if (op_type == IS_UNUSED) {
     474             :                 if (EXPECTED(Z_OBJ(EX(This)) != NULL)) {
     475             :                         *should_free = NULL;
     476             :                         return &EX(This);
     477             :                 } else {
     478             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     479             :                 }
     480             :         }
     481             :         return get_zval_ptr(op_type, op, execute_data, should_free, type);
     482             : }
     483             : 
     484             : 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)
     485             : {
     486             :         if (op_type == IS_UNUSED) {
     487             :                 if (EXPECTED(Z_OBJ(EX(This)) != NULL)) {
     488             :                         *should_free = NULL;
     489             :                         return &EX(This);
     490             :                 } else {
     491             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     492             :                 }
     493             :         }
     494             :         return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type);
     495             : }
     496             : 
     497      945975 : static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr)
     498             : {
     499      945975 :         if (EXPECTED(variable_ptr != value_ptr)) {
     500             :                 zend_reference *ref;
     501     1890796 :                 ZVAL_MAKE_REF(value_ptr);
     502             :                 Z_ADDREF_P(value_ptr);
     503      945398 :                 ref = Z_REF_P(value_ptr);
     504             : 
     505             :                 zval_ptr_dtor(variable_ptr);
     506      945398 :                 ZVAL_REF(variable_ptr, ref);
     507             :         } else {
     508        1154 :                 ZVAL_MAKE_REF(variable_ptr);
     509             :         }
     510      945975 : }
     511             : 
     512             : /* this should modify object only if it's empty */
     513          21 : static inline int make_real_object(zval **object_ptr)
     514             : {
     515          21 :         zval *object = *object_ptr;
     516             : 
     517          21 :         ZVAL_DEREF(object);
     518          21 :         if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     519          42 :                 if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE)
     520          22 :                         || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
     521             :                         zval_ptr_dtor_nogc(object);
     522          11 :                         object_init(object);
     523          11 :                         zend_error(E_WARNING, "Creating default object from empty value");
     524             :                 } else {
     525           7 :                         return 0;
     526             :                 }
     527             :         }
     528          14 :         *object_ptr = object;
     529          14 :         return 1;
     530             : }
     531             : 
     532        1154 : ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
     533             : {
     534             :         zend_string *key;
     535             :         ALLOCA_FLAG(use_heap);
     536             : 
     537        1154 :         STR_ALLOCA_INIT(key, cur_arg_info->class_name, strlen(cur_arg_info->class_name), use_heap);
     538        1154 :         *pce = zend_fetch_class(key, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
     539        1154 :         STR_ALLOCA_FREE(key, use_heap);
     540             : 
     541        1154 :         *class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name;
     542        1154 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     543         472 :                 return "implement interface ";
     544             :         } else {
     545         682 :                 return "be an instance of ";
     546             :         }
     547             : }
     548             : 
     549       87899 : ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
     550             : {
     551       87899 :         *pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
     552             : 
     553       87899 :         *class_name = (*pce) ? (*pce)->name->val : cur_arg_info->class_name->val;
     554       87899 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     555         169 :                 return "implement interface ";
     556             :         } else {
     557       87730 :                 return "be an instance of ";
     558             :         }
     559             : }
     560             : 
     561         225 : ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uint32_t arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind, zval *arg)
     562             : {
     563         225 :         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
     564         225 :         const char *fname = zf->common.function_name->val;
     565             :         const char *fsep;
     566             :         const char *fclass;
     567             :         zval old_arg;
     568             : 
     569         225 :         if (zf->common.scope) {
     570          30 :                 fsep =  "::";
     571          30 :                 fclass = zf->common.scope->name->val;
     572             :         } else {
     573         195 :                 fsep =  "";
     574         195 :                 fclass = "";
     575             :         }
     576             : 
     577         225 :         if (zf->common.type == ZEND_USER_FUNCTION) {
     578          30 :                 if (arg) {
     579          25 :                         ZVAL_COPY_VALUE(&old_arg, arg);
     580          25 :                         ZVAL_UNDEF(arg);
     581             :                 }
     582             : 
     583          39 :                 if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     584          28 :                         zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind, ptr->func->op_array.filename->val, ptr->opline->lineno);
     585             :                 } else {
     586           2 :                         zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
     587             :                 }
     588             : 
     589           9 :                 if (arg) {
     590           8 :                         ZVAL_COPY_VALUE(arg, &old_arg);
     591             :                 }
     592             :         } else {
     593         195 :                 zend_error(error_type, "Argument %d passed to %s%s%s() must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, given_msg, given_kind);
     594             :         }
     595         163 : }
     596             : 
     597           3 : static int is_null_constant(zval *default_value)
     598             : {
     599           3 :         if (Z_CONSTANT_P(default_value)) {
     600             :                 zval constant;
     601             : 
     602           3 :                 ZVAL_COPY_VALUE(&constant, default_value);
     603           3 :                 zval_update_constant(&constant, 0);
     604           3 :                 if (Z_TYPE(constant) == IS_NULL) {
     605           2 :                         return 1;
     606             :                 }
     607             :                 zval_dtor(&constant);
     608             :         }
     609           1 :         return 0;
     610             : }
     611             : 
     612        2207 : static void zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, zval *arg)
     613             : {
     614             :         zend_internal_arg_info *cur_arg_info;
     615             :         char *need_msg;
     616             :         zend_class_entry *ce;
     617             : 
     618        2207 :         if (EXPECTED(arg_num <= zf->internal_function.num_args)) {
     619        2174 :                 cur_arg_info = &zf->internal_function.arg_info[arg_num-1];
     620          33 :         } else if (zf->internal_function.fn_flags & ZEND_ACC_VARIADIC) {
     621           0 :                 cur_arg_info = &zf->internal_function.arg_info[zf->internal_function.num_args];
     622             :         } else {
     623          33 :                 return;
     624             :         }
     625             : 
     626        2174 :         if (cur_arg_info->class_name) {
     627             :                 char *class_name;
     628             : 
     629        1157 :                 ZVAL_DEREF(arg);
     630        1157 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     631        1036 :                         need_msg = zend_verify_internal_arg_class_kind((zend_internal_arg_info*)cur_arg_info, &class_name, &ce);
     632        1036 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce)) {
     633          70 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg);
     634             :                         }
     635         121 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
     636         118 :                         need_msg = zend_verify_internal_arg_class_kind((zend_internal_arg_info*)cur_arg_info, &class_name, &ce);
     637         118 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg);
     638             :                 }
     639        1017 :         } else if (cur_arg_info->type_hint) {
     640         322 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     641         322 :                         ZVAL_DEREF(arg);
     642         342 :                         if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     643           7 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg);
     644             :                         }
     645           0 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     646           0 :                         if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     647           0 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg);
     648             :                         }
     649             : #if ZEND_DEBUG
     650             :                 } else {
     651             :                         zend_error(E_ERROR, "Unknown typehint");
     652             : #endif
     653             :                 }
     654             :         }
     655             : }
     656             : 
     657       88278 : static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value)
     658             : {
     659             :         zend_arg_info *cur_arg_info;
     660             :         char *need_msg;
     661             :         zend_class_entry *ce;
     662             : 
     663       88278 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     664       88269 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     665           9 :         } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
     666           9 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args];
     667             :         } else {
     668           0 :                 return;
     669             :         }
     670             : 
     671       88278 :         if (cur_arg_info->class_name) {
     672             :                 char *class_name;
     673             : 
     674       87934 :                 ZVAL_DEREF(arg);
     675       87934 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     676       87890 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce);
     677       87890 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce)) {
     678          12 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg);
     679             :                         }
     680          44 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value)))) {
     681           7 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce);
     682           7 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg);
     683             :                 }
     684         344 :         } else if (cur_arg_info->type_hint) {
     685         170 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     686         162 :                         ZVAL_DEREF(arg);
     687         173 :                         if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value))))) {
     688           6 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg);
     689             :                         }
     690           8 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     691           8 :                         if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value))))) {
     692           0 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg);
     693             :                         }
     694             : #if ZEND_DEBUG
     695             :                 } else {
     696             :                         zend_error(E_ERROR, "Unknown typehint");
     697             : #endif
     698             :                 }
     699             :         }
     700             : }
     701             : 
     702           5 : static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_num)
     703             : {
     704             :         zend_arg_info *cur_arg_info;
     705             :         char *need_msg;
     706             :         zend_class_entry *ce;
     707             : 
     708           5 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     709           5 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     710           0 :         } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
     711           0 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args];
     712             :         } else {
     713           0 :                 return 1;
     714             :         }
     715             : 
     716           5 :         if (cur_arg_info->class_name) {
     717             :                 char *class_name;
     718             : 
     719           2 :                 need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce);
     720           2 :                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "", NULL);
     721           0 :                 return 0;
     722           3 :         } else if (cur_arg_info->type_hint) {
     723           3 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     724           2 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "", NULL);
     725           1 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     726           1 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "", NULL);
     727             : #if ZEND_DEBUG
     728             :                 } else {
     729             :                         zend_error(E_ERROR, "Unknown typehint");
     730             : #endif
     731             :                 }
     732           1 :                 return 0;
     733             :         }
     734           0 :         return 1;
     735             : }
     736             : 
     737          75 : static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t arg_num)
     738             : {
     739          76 :         if (EXPECTED(!(EX(func)->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) ||
     740           5 :             zend_verify_missing_arg_type(EX(func), arg_num)) {
     741          70 :                 const char *class_name = EX(func)->common.scope ? EX(func)->common.scope->name->val : "";
     742          70 :                 const char *space = EX(func)->common.scope ? "::" : "";
     743          70 :                 const char *func_name = EX(func)->common.function_name ? EX(func)->common.function_name->val : "main";
     744          70 :                 zend_execute_data *ptr = EX(prev_execute_data);
     745             : 
     746          85 :                 if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     747          15 :                         zend_error(E_WARNING, "Missing argument %u for %s%s%s(), called in %s on line %d and defined", arg_num, class_name, space, func_name, ptr->func->op_array.filename->val, ptr->opline->lineno);
     748             :                 } else {
     749          55 :                         zend_error(E_WARNING, "Missing argument %u for %s%s%s()", arg_num, class_name, space, func_name);
     750             :                 }
     751             :         }
     752          71 : }
     753             : 
     754             : static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, uint32_t object_op_type, zval *property_name, uint32_t property_op_type, int value_type, znode_op value_op, const zend_execute_data *execute_data, void **cache_slot)
     755             : {
     756             :         zend_free_op free_value;
     757      113569 :         zval *value = get_zval_ptr_deref(value_type, value_op, execute_data, &free_value, BP_VAR_R);
     758             :         zval tmp;
     759             : 
     760      125246 :         if (object_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     761             :                 do {
     762       10072 :                         if (object_op_type == IS_VAR && UNEXPECTED(object == &EG(error_zval))) {
     763           0 :                                 if (retval) {
     764           0 :                                         ZVAL_NULL(retval);
     765             :                                 }
     766           0 :                                 FREE_OP(free_value);
     767             :                                 return;
     768             :                         }
     769       10072 :                         if (Z_ISREF_P(object)) {
     770       10044 :                                 object = Z_REFVAL_P(object);
     771       10044 :                                 if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
     772             :                                         break;
     773             :                                 }
     774             :                         }
     775          33 :                         if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE ||
     776             :                         (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
     777             :                                 zend_object *obj;
     778             : 
     779             :                                 zval_ptr_dtor(object);
     780          24 :                                 object_init(object);
     781             :                                 Z_ADDREF_P(object);
     782          24 :                                 obj = Z_OBJ_P(object);
     783          24 :                                 zend_error(E_WARNING, "Creating default object from empty value");
     784          24 :                                 if (GC_REFCOUNT(obj) == 1) {
     785             :                                         /* the enclosing container was deleted, obj is unreferenced */
     786           1 :                                         if (retval) {
     787           1 :                                                 ZVAL_NULL(retval);
     788             :                                         }
     789           1 :                                         FREE_OP(free_value);
     790             :                                         OBJ_RELEASE(obj);
     791             :                                         return;
     792             :                                 }
     793             :                                 Z_DELREF_P(object);
     794             :                         } else {
     795           4 :                                 zend_error(E_WARNING, "Attempt to assign property of non-object");
     796           4 :                                 if (retval) {
     797           0 :                                         ZVAL_NULL(retval);
     798             :                                 }
     799           4 :                                 FREE_OP(free_value);
     800             :                                 return;
     801             :                         }
     802             :                 } while (0);
     803             :         }
     804             : 
     805      216980 :         if (property_op_type == IS_CONST &&
     806      103416 :                 EXPECTED(Z_OBJCE_P(object) == CACHED_PTR_EX(cache_slot))) {
     807      101157 :                 uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
     808      101157 :                 zend_object *zobj = Z_OBJ_P(object);
     809             :                 zval *property;
     810             : 
     811      101157 :                 if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
     812       90431 :                         property = OBJ_PROP(zobj, prop_offset);
     813       90431 :                         if (Z_TYPE_P(property) != IS_UNDEF) {
     814             : fast_assign:
     815      181198 :                                 value = zend_assign_to_variable(property, value, value_type);
     816       90599 :                                 if (retval && !EG(exception)) {
     817           0 :                                         ZVAL_COPY(retval, value);
     818             :                                 }
     819       90599 :                                 if (value_type == IS_VAR) {
     820         167 :                                         FREE_OP(free_value);
     821             :                                 }
     822             :                                 return;
     823             :                         }
     824             :                 } else {
     825       10726 :                         if (EXPECTED(zobj->properties != NULL)) {
     826         480 :                                 property = zend_hash_find(zobj->properties, Z_STR_P(property_name));
     827         480 :                                 if (property) {
     828             :                                         goto fast_assign;
     829             :                                 }
     830             :                         }
     831             : 
     832       10556 :                         if (!zobj->ce->__set) {
     833       10551 :                                 if (EXPECTED(zobj->properties == NULL)) {
     834       10241 :                                         rebuild_object_properties(zobj);
     835             :                                 }
     836             :                                 /* separate our value if necessary */
     837       10551 :                                 if (value_type == IS_CONST) {
     838       10186 :                                         if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
     839           2 :                                                 ZVAL_COPY_VALUE(&tmp, value);
     840           2 :                                                 zval_copy_ctor_func(&tmp);
     841           2 :                                                 value = &tmp;
     842             :                                         }
     843         635 :                                 } else if (value_type != IS_TMP_VAR &&
     844         270 :                                            Z_REFCOUNTED_P(value)) {
     845             :                                         Z_ADDREF_P(value);
     846             :                                 }
     847       10551 :                                 zend_hash_add_new(zobj->properties, Z_STR_P(property_name), value);
     848       10551 :                                 if (retval && !EG(exception)) {
     849           0 :                                         ZVAL_COPY(retval, value);
     850             :                                 }
     851       10551 :                                 if (value_type == IS_VAR) {
     852         105 :                                         FREE_OP(free_value);
     853             :                                 }
     854             :                                 return;
     855             :                         }
     856             :         }
     857             :         }
     858             : 
     859       12414 :         if (!Z_OBJ_HT_P(object)->write_property) {
     860           0 :                 zend_error(E_WARNING, "Attempt to assign property of non-object");
     861           0 :                 if (retval) {
     862           0 :                         ZVAL_NULL(retval);
     863             :                 }
     864           0 :                 FREE_OP(free_value);
     865             :                 return;
     866             :         }
     867             : 
     868             :         /* separate our value if necessary */
     869       12414 :         if (value_type == IS_CONST) {
     870        1180 :                 if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
     871          40 :                         ZVAL_COPY_VALUE(&tmp, value);
     872          40 :                         zval_copy_ctor_func(&tmp);
     873          40 :                         value = &tmp;
     874             :                 }
     875       22312 :         } else if (value_type != IS_TMP_VAR &&
     876       11078 :                    Z_REFCOUNTED_P(value)) {
     877             :                 Z_ADDREF_P(value);
     878             :         }
     879             : 
     880       12414 :         Z_OBJ_HT_P(object)->write_property(object, property_name, value, cache_slot);
     881             : 
     882       12406 :         if (retval && !EG(exception)) {
     883          25 :                 ZVAL_COPY(retval, value);
     884             :         }
     885             :         zval_ptr_dtor(value);
     886       12406 :         if (value_type == IS_VAR) {
     887         257 :                 FREE_OP(free_value);
     888             :         }
     889             : }
     890             : 
     891             : static zend_always_inline void zend_assign_to_object_dim(zval *retval, zval *object, zval *property_name, int value_type, znode_op value_op, const zend_execute_data *execute_data)
     892             : {
     893             :         zend_free_op free_value;
     894        1555 :         zval *value = get_zval_ptr_deref(value_type, value_op, execute_data, &free_value, BP_VAR_R);
     895             :         zval tmp;
     896             : 
     897             :         /* Note:  property_name in this case is really the array index! */
     898        1555 :         if (!Z_OBJ_HT_P(object)->write_dimension) {
     899           0 :                 zend_error_noreturn(E_ERROR, "Cannot use object as array");
     900             :         }
     901             : 
     902             :         /* separate our value if necessary */
     903        1555 :         if (value_type == IS_CONST) {
     904        1446 :                 if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
     905           1 :                         ZVAL_COPY_VALUE(&tmp, value);
     906           1 :                         zval_copy_ctor_func(&tmp);
     907           1 :                         value = &tmp;
     908             :                 }
     909         201 :         } else if (value_type != IS_TMP_VAR &&
     910          92 :                    Z_REFCOUNTED_P(value)) {
     911             :                 Z_ADDREF_P(value);
     912             :         }
     913             : 
     914        1555 :         Z_OBJ_HT_P(object)->write_dimension(object, property_name, value);
     915             : 
     916        1553 :         if (retval && !EG(exception)) {
     917           5 :                 ZVAL_COPY(retval, value);
     918             :         }
     919             :         zval_ptr_dtor(value);
     920        1553 :         if (value_type == IS_VAR) {
     921          14 :                 FREE_OP(free_value);
     922             :         }
     923             : }
     924             : 
     925          10 : static void zend_binary_assign_op_obj_dim(zval *object, zval *property, zval *value, zval *retval, int (*binary_op)(zval *result, zval *op1, zval *op2))
     926             : {
     927             :         zval *z;
     928             :         zval rv;
     929             : 
     930          30 :         if (Z_OBJ_HT_P(object)->read_dimension &&
     931          10 :                 (z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) {
     932             : 
     933          10 :                 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
     934             :                         zval rv;
     935           4 :                         zval *value = Z_OBJ_HT_P(z)->get(z, &rv);
     936             : 
     937           4 :                         if (Z_REFCOUNT_P(z) == 0) {
     938           0 :                                 zend_objects_store_del(Z_OBJ_P(z));
     939             :                         }
     940           4 :                         ZVAL_COPY_VALUE(z, value);
     941             :                 }
     942          10 :                 ZVAL_DEREF(z);
     943          20 :                 SEPARATE_ZVAL_NOREF(z);
     944          10 :                 binary_op(z, z, value);
     945          10 :                 Z_OBJ_HT_P(object)->write_dimension(object, property, z);
     946          10 :                 if (retval) {
     947           0 :                         ZVAL_COPY(retval, z);
     948             :                 }
     949             :                 zval_ptr_dtor(z);
     950             :         } else {
     951           0 :                 zend_error(E_WARNING, "Attempt to assign property of non-object");
     952           0 :                 if (retval) {
     953           0 :                         ZVAL_NULL(retval);
     954             :                 }
     955             :         }
     956          10 : }
     957             : 
     958         145 : static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result)
     959             : {
     960             :         zend_string *old_str;
     961             : 
     962         145 :         if (offset < 0) {
     963           1 :                 zend_error(E_WARNING, "Illegal string offset:  " ZEND_LONG_FMT, offset);
     964           1 :                 zend_string_release(Z_STR_P(str));
     965           1 :                 if (result) {
     966           0 :                         ZVAL_NULL(result);
     967             :                 }
     968           1 :                 return;
     969             :         }
     970             : 
     971         144 :         old_str = Z_STR_P(str);
     972         144 :         if ((size_t)offset >= Z_STRLEN_P(str)) {
     973           3 :                 zend_long old_len = Z_STRLEN_P(str);
     974           6 :                 Z_STR_P(str) = zend_string_realloc(Z_STR_P(str), offset + 1, 0);
     975           3 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
     976           3 :                 memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
     977           3 :                 Z_STRVAL_P(str)[offset+1] = 0;
     978         141 :         } else if (!Z_REFCOUNTED_P(str)) {
     979          16 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
     980           8 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
     981             :         }
     982             : 
     983         144 :         if (Z_TYPE_P(value) != IS_STRING) {
     984          11 :                 zend_string *tmp = zval_get_string(value);
     985             : 
     986          11 :                 Z_STRVAL_P(str)[offset] = tmp->val[0];
     987             :                 zend_string_release(tmp);
     988             :         } else {
     989         133 :                 Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
     990             :         }
     991             :         /*
     992             :          * the value of an assignment to a string offset is undefined
     993             :         T(result->u.var).var = &T->str_offset.str;
     994             :         */
     995             : 
     996             :         zend_string_release(old_str);
     997         144 :         if (result) {
     998          12 :                 zend_uchar c = (zend_uchar)Z_STRVAL_P(str)[offset];
     999             : 
    1000          12 :                 if (CG(one_char_string)[c]) {
    1001           0 :                         ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1002             :                 } else {
    1003          24 :                         ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(str) + offset, 1, 0));
    1004             :                 }
    1005             :         }
    1006             : }
    1007             : 
    1008             : /* Utility Functions for Extensions */
    1009           0 : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array)
    1010             : {
    1011           0 :         if (extension->statement_handler) {
    1012           0 :                 extension->statement_handler(op_array);
    1013             :         }
    1014           0 : }
    1015             : 
    1016             : 
    1017           0 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array)
    1018             : {
    1019           0 :         if (extension->fcall_begin_handler) {
    1020           0 :                 extension->fcall_begin_handler(op_array);
    1021             :         }
    1022           0 : }
    1023             : 
    1024             : 
    1025           0 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array)
    1026             : {
    1027           0 :         if (extension->fcall_end_handler) {
    1028           0 :                 extension->fcall_end_handler(op_array);
    1029             :         }
    1030           0 : }
    1031             : 
    1032             : 
    1033             : static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_data *execute_data, int fetch_type)
    1034             : {
    1035             :         HashTable *ht;
    1036             : 
    1037      214690 :         if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
    1038      107345 :             EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
    1039       13446 :                 ht = &EG(symbol_table).ht;
    1040       93899 :         } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
    1041             :                 ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
    1042        1441 :                 ht = EX(func)->op_array.static_variables;
    1043             :         } else {
    1044             :                 ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
    1045       92458 :                 if (!EX(symbol_table)) {
    1046       87388 :                         zend_rebuild_symbol_table();
    1047             :                 }
    1048       92458 :                 ht = &EX(symbol_table)->ht;
    1049             :         }
    1050      107345 :         return ht;
    1051             : }
    1052             : 
    1053             : static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type)
    1054             : {
    1055             :         zval *retval;
    1056             :         zend_string *offset_key;
    1057             :         zend_ulong hval;
    1058             : 
    1059             : try_again:
    1060     9949794 :         if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
    1061     5139434 :                 hval = Z_LVAL_P(dim);
    1062             : num_index:
    1063     5319583 :                 retval = zend_hash_index_find(ht, hval);
    1064     5319583 :                 if (retval == NULL) {
    1065      396993 :                         switch (type) {
    1066             :                                 case BP_VAR_R:
    1067          16 :                                         zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
    1068             :                                         /* break missing intentionally */
    1069             :                                 case BP_VAR_UNSET:
    1070             :                                 case BP_VAR_IS:
    1071          19 :                                         retval = &EG(uninitialized_zval);
    1072             :                                         break;
    1073             :                                 case BP_VAR_RW:
    1074           6 :                                         zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
    1075             :                                         /* break missing intentionally */
    1076             :                                 case BP_VAR_W:
    1077      396974 :                                         retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
    1078             :                                         break;
    1079             :                         }
    1080             :                 }
    1081     4810360 :         } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
    1082     3711658 :                 offset_key = Z_STR_P(dim);
    1083     3711658 :                 if (dim_type != IS_CONST) {
    1084     6072940 :                         if (ZEND_HANDLE_NUMERIC(offset_key, hval)) {
    1085             :                                 goto num_index;
    1086             :                         }
    1087             :                 }
    1088             : str_index:
    1089     3531584 :                 retval = zend_hash_find(ht, offset_key);
    1090     3531584 :                 if (retval) {
    1091             :                         /* support for $GLOBALS[...] */
    1092     1580033 :                         if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
    1093        7883 :                                 retval = Z_INDIRECT_P(retval);
    1094        7883 :                                 if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
    1095          21 :                                         switch (type) {
    1096             :                                                 case BP_VAR_R:
    1097           1 :                                                         zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
    1098             :                                                         /* break missing intentionally */
    1099             :                                                 case BP_VAR_UNSET:
    1100             :                                                 case BP_VAR_IS:
    1101           1 :                                                         retval = &EG(uninitialized_zval);
    1102             :                                                         break;
    1103             :                                                 case BP_VAR_RW:
    1104           0 :                                                         zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
    1105             :                                                         /* break missing intentionally */
    1106             :                                                 case BP_VAR_W:
    1107          20 :                                                         ZVAL_NULL(retval);
    1108             :                                                         break;
    1109             :                                         }
    1110             :                                 }
    1111             :                         }
    1112             :                 } else {
    1113     1951551 :                         switch (type) {
    1114             :                                 case BP_VAR_R:
    1115      158525 :                                         zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
    1116             :                                         /* break missing intentionally */
    1117             :                                 case BP_VAR_UNSET:
    1118             :                                 case BP_VAR_IS:
    1119      158525 :                                         retval = &EG(uninitialized_zval);
    1120             :                                         break;
    1121             :                                 case BP_VAR_RW:
    1122           1 :                                         zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
    1123             :                                         /* break missing intentionally */
    1124             :                                 case BP_VAR_W:
    1125     1793026 :                                         retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
    1126             :                                         break;
    1127             :                         }
    1128             :                 }
    1129             :         } else {
    1130     1098702 :                 switch (Z_TYPE_P(dim)) {
    1131             :                         case IS_NULL:
    1132          11 :                                 offset_key = STR_EMPTY_ALLOC();
    1133             :                                 goto str_index;
    1134             :                         case IS_DOUBLE:
    1135         104 :                                 hval = zend_dval_to_lval(Z_DVAL_P(dim));
    1136             :                                 goto num_index;
    1137             :                         case IS_RESOURCE:
    1138           3 :                                 zend_error(E_STRICT, "Resource ID#%pd used as offset, casting to integer (%pd)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
    1139           3 :                                 hval = Z_RES_HANDLE_P(dim);
    1140             :                                 goto num_index;
    1141             :                         case IS_FALSE:
    1142           6 :                                 hval = 0;
    1143             :                                 goto num_index;
    1144             :                         case IS_TRUE:
    1145           3 :                                 hval = 1;
    1146             :                                 goto num_index;
    1147             :                         case IS_REFERENCE:
    1148     1098621 :                                 dim = Z_REFVAL_P(dim);
    1149             :                                 goto try_again;
    1150             :                         default:
    1151           6 :                                 zend_error(E_WARNING, "Illegal offset type");
    1152           6 :                                 retval = (type == BP_VAR_W || type == BP_VAR_RW) ?
    1153             :                                         &EG(error_zval) : &EG(uninitialized_zval);
    1154             :                 }
    1155             :         }
    1156     8851173 :         return retval;
    1157             : }
    1158             : 
    1159         152 : static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type)
    1160             : {
    1161             :         zend_long offset;
    1162             : 
    1163         152 :         if (dim == NULL) {
    1164           0 :                 zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
    1165             :         }
    1166             : 
    1167             : try_again:
    1168         152 :         if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1169          15 :                 switch(Z_TYPE_P(dim)) {
    1170             :                         case IS_STRING:
    1171          30 :                                 if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1172           0 :                                         break;
    1173             :                                 }
    1174          15 :                                 if (type != BP_VAR_UNSET) {
    1175          14 :                                         zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1176             :                                 }
    1177          15 :                                 break;
    1178             :                         case IS_DOUBLE:
    1179             :                         case IS_NULL:
    1180             :                         case IS_FALSE:
    1181             :                         case IS_TRUE:
    1182           0 :                                 zend_error(E_NOTICE, "String offset cast occurred");
    1183           0 :                                 break;
    1184             :                         case IS_REFERENCE:
    1185           0 :                                 dim = Z_REFVAL_P(dim);
    1186           0 :                                 goto try_again;
    1187             :                         default:
    1188           0 :                                 zend_error(E_WARNING, "Illegal offset type");
    1189             :                                 break;
    1190             :                 }
    1191             : 
    1192          15 :                 offset = zval_get_long(dim);
    1193             :         } else {
    1194         137 :                 offset = Z_LVAL_P(dim);
    1195             :         }
    1196             : 
    1197         152 :         return offset;
    1198             : }
    1199             : 
    1200             : static zend_always_inline zend_long zend_fetch_string_offset(zval *container, zval *dim, int type)
    1201             : {
    1202         145 :         zend_long offset = zend_check_string_offset(dim, type);
    1203             : 
    1204         145 :         if (Z_REFCOUNTED_P(container)) {
    1205         136 :                 if (Z_REFCOUNT_P(container) > 1) {
    1206             :                         Z_DELREF_P(container);
    1207           6 :                         zval_copy_ctor_func(container);
    1208             :                 }
    1209             :                 Z_ADDREF_P(container);
    1210             :         }
    1211         145 :         return offset;
    1212             : }
    1213             : 
    1214             : static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container, zval *dim, int dim_type, int type)
    1215             : {
    1216             :     zval *retval;
    1217             : 
    1218             : try_again:
    1219     4533454 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1220     9118028 :                 SEPARATE_ARRAY(container);
    1221             : fetch_from_array:
    1222     4509630 :                 if (dim == NULL) {
    1223      564587 :                         retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
    1224      564587 :                         if (UNEXPECTED(retval == NULL)) {
    1225           1 :                                 zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
    1226           1 :                                 retval = &EG(error_zval);
    1227             :                         }
    1228             :                 } else {
    1229     7890086 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
    1230             :                 }
    1231     4509630 :                 ZVAL_INDIRECT(result, retval);
    1232       24984 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1233          11 :                 if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
    1234             :                         zval_ptr_dtor_nogc(container);
    1235             : convert_to_array:
    1236        1160 :                         ZVAL_NEW_ARR(container);
    1237        1160 :                         zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
    1238             :                         goto fetch_from_array;
    1239             :                 }
    1240             : 
    1241           7 :                 zend_check_string_offset(dim, type);
    1242             : 
    1243           7 :                 ZVAL_INDIRECT(result, NULL); /* wrong string offset */
    1244       24973 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1245          52 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1246           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1247             :                 } else {
    1248          52 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result);
    1249             : 
    1250          52 :                         if (UNEXPECTED(retval == &EG(uninitialized_zval))) {
    1251           2 :                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1252             : 
    1253           2 :                                 ZVAL_NULL(result);
    1254           2 :                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
    1255          96 :                         } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) {
    1256          46 :                                 if (!Z_ISREF_P(retval)) {
    1257          76 :                                         if (Z_REFCOUNTED_P(retval) &&
    1258             :                                             Z_REFCOUNT_P(retval) > 1) {
    1259           7 :                                                 if (Z_TYPE_P(retval) != IS_OBJECT) {
    1260             :                                                         Z_DELREF_P(retval);
    1261           5 :                                                         ZVAL_DUP(result, retval);
    1262           5 :                                                         retval = result;
    1263             :                                                 } else {
    1264           2 :                                                         ZVAL_COPY(result, retval);
    1265           2 :                                                         retval = result;
    1266             :                                                 }
    1267             :                                         }
    1268          40 :                                         if (Z_TYPE_P(retval) != IS_OBJECT) {
    1269           9 :                                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1270           9 :                                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
    1271             :                                         }
    1272             :                                 }
    1273          46 :                                 if (result != retval) {
    1274           5 :                                         ZVAL_INDIRECT(result, retval);
    1275             :                                 }
    1276             :                         } else {
    1277           4 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1278             :                         }
    1279             :                 }
    1280       24921 :         } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
    1281        1158 :                 if (UNEXPECTED(container == &EG(error_zval))) {
    1282           2 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1283        1156 :                 } else if (type != BP_VAR_UNSET) {
    1284             :                         goto convert_to_array;
    1285             :                 } else {
    1286             :                         /* for read-mode only */
    1287           0 :                         ZVAL_NULL(result);
    1288             :                 }
    1289       23763 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
    1290       23744 :                 container = Z_REFVAL_P(container);
    1291             :                 goto try_again;
    1292             :         } else {
    1293          19 :                 if (type == BP_VAR_UNSET) {
    1294           0 :                         zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
    1295           0 :                         ZVAL_NULL(result);
    1296             :                 } else {
    1297          19 :                         zend_error(E_WARNING, "Cannot use a scalar value as an array");
    1298          19 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1299             :                 }
    1300             :         }
    1301             : }
    1302             : 
    1303     3240907 : static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1304             : {
    1305             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W);
    1306     3240907 : }
    1307             : 
    1308     1268785 : static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1309             : {
    1310             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW);
    1311     1268785 : }
    1312             : 
    1313          18 : static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1314             : {
    1315             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET);
    1316          18 : }
    1317             : 
    1318             : static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type)
    1319             : {
    1320             :         zval *retval;
    1321             : 
    1322             : try_again:
    1323     5827686 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1324     9398148 :                 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
    1325     4699074 :                 ZVAL_COPY(result, retval);
    1326     1128612 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1327             :                 zend_long offset;
    1328             : 
    1329             : try_string_offset:
    1330       32117 :                 if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1331          46 :                         switch(Z_TYPE_P(dim)) {
    1332             :                                 /* case IS_LONG: */
    1333             :                                 case IS_STRING:
    1334          60 :                                         if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1335             :                                                 break;
    1336             :                                         }
    1337          29 :                                         if (type != BP_VAR_IS) {
    1338          21 :                                                 zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1339             :                                         }
    1340             :                                         break;
    1341             :                                 case IS_DOUBLE:
    1342             :                                 case IS_NULL:
    1343             :                                 case IS_FALSE:
    1344             :                                 case IS_TRUE:
    1345          13 :                                         if (type != BP_VAR_IS) {
    1346          11 :                                                 zend_error(E_NOTICE, "String offset cast occurred");
    1347             :                                         }
    1348             :                                         break;
    1349             :                                 case IS_REFERENCE:
    1350           0 :                                         dim = Z_REFVAL_P(dim);
    1351             :                                         goto try_string_offset;
    1352             :                                 default:
    1353           3 :                                         zend_error(E_WARNING, "Illegal offset type");
    1354             :                                         break;
    1355             :                         }
    1356             : 
    1357          46 :                         offset = zval_get_long(dim);
    1358             :                 } else {
    1359       32071 :                         offset = Z_LVAL_P(dim);
    1360             :                 }
    1361             : 
    1362       32117 :                 if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) {
    1363          37 :                         if (type != BP_VAR_IS) {
    1364          33 :                                 zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset);
    1365             :                         }
    1366          37 :                         ZVAL_EMPTY_STRING(result);
    1367             :                 } else {
    1368       32080 :                         zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset];
    1369             : 
    1370       32080 :                         if (CG(one_char_string)[c]) {
    1371           0 :                                 ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1372             :                         } else {
    1373       64160 :                                 ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(container) + offset, 1, 0));
    1374             :                         }
    1375             :                 }
    1376     1096495 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1377         759 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1378           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1379             :                 } else {
    1380         759 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result);
    1381             : 
    1382             :                         ZEND_ASSERT(result != NULL);
    1383         756 :                         if (retval) {
    1384         748 :                                 if (result != retval) {
    1385         121 :                                         ZVAL_COPY(result, retval);
    1386             :                                 }
    1387             :                         } else {
    1388           8 :                                 ZVAL_NULL(result);
    1389             :                         }
    1390             :                 }
    1391     1095736 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
    1392     1095609 :                 container = Z_REFVAL_P(container);
    1393             :                 goto try_again;
    1394             :         } else {
    1395         127 :                 ZVAL_NULL(result);
    1396             :         }
    1397             : }
    1398             : 
    1399     4731197 : static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type)
    1400             : {
    1401             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R);
    1402     4731194 : }
    1403             : 
    1404         880 : static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type)
    1405             : {
    1406             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS);
    1407         880 : }
    1408             : 
    1409          11 : ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim)
    1410             : {
    1411          11 :         zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR);
    1412          11 : }
    1413             : 
    1414             : 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)
    1415             : {
    1416      263342 :     if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
    1417             :                 do {
    1418          86 :                         if (container_op_type != IS_VAR && UNEXPECTED(container == &EG(error_zval))) {
    1419           0 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1420             :                                 return;
    1421             :                         }
    1422             : 
    1423          86 :                         if (Z_ISREF_P(container)) {
    1424          42 :                                 container = Z_REFVAL_P(container);
    1425          42 :                                 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1426             :                                         break;
    1427             :                                 }
    1428             :                         }
    1429             : 
    1430             :                         /* this should modify object only if it's empty */
    1431          97 :                         if (type != BP_VAR_UNSET &&
    1432           3 :                             EXPECTED(Z_TYPE_P(container) <= IS_FALSE ||
    1433             :                               (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0))) {
    1434             :                                 zval_ptr_dtor_nogc(container);
    1435          38 :                                 object_init(container);
    1436             :                         } else {
    1437           6 :                                 zend_error(E_WARNING, "Attempt to modify property of non-object");
    1438           6 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1439             :                                 return;
    1440             :                         }
    1441             :                 } while (0);
    1442             :         }
    1443      351136 :         if (prop_op_type == IS_CONST &&
    1444      175559 :             EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) {
    1445      175104 :                 uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
    1446      175104 :                 zend_object *zobj = Z_OBJ_P(container);
    1447             :                 zval *retval;
    1448             : 
    1449      175104 :                 if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
    1450      174992 :                         retval = OBJ_PROP(zobj, prop_offset);
    1451      174992 :                         if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
    1452      174992 :                                 ZVAL_INDIRECT(result, retval);
    1453             :                                 return;
    1454             :                         }
    1455         112 :                 } else if (EXPECTED(zobj->properties != NULL)) {
    1456         106 :                         retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
    1457         106 :                         if (EXPECTED(retval)) {
    1458           2 :                                 ZVAL_INDIRECT(result, retval);
    1459             :                                 return;
    1460             :                         }
    1461             :                 }
    1462             :         }
    1463         583 :         if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
    1464         583 :                 zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot);
    1465         582 :                 if (NULL == ptr) {
    1466         110 :                         if (Z_OBJ_HT_P(container)->read_property &&
    1467          55 :                                 (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result)) != NULL) {
    1468          55 :                                 if (ptr != result) {
    1469           2 :                                         ZVAL_INDIRECT(result, ptr);
    1470             :                                 }
    1471             :                         } else {
    1472           0 :                                 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
    1473             :                         }
    1474             :                 } else {
    1475         527 :                         ZVAL_INDIRECT(result, ptr);
    1476             :                 }
    1477           0 :         } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
    1478           0 :                 zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result);
    1479           0 :                 if (ptr != result) {
    1480           0 :                         ZVAL_INDIRECT(result, ptr);
    1481             :                 }
    1482             :         } else {
    1483           0 :                 zend_error(E_WARNING, "This object doesn't support property references");
    1484           0 :                 ZVAL_INDIRECT(result, &EG(error_zval));
    1485             :         }
    1486             : }
    1487             : 
    1488       79539 : static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const zend_execute_data *execute_data)
    1489             : {
    1490       79539 :         int original_nest_levels = nest_levels;
    1491             :         zend_brk_cont_element *jmp_to;
    1492             : 
    1493             :         do {
    1494       79701 :                 if (array_offset==-1) {
    1495           1 :                         zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
    1496             :                 }
    1497       79700 :                 jmp_to = &op_array->brk_cont_array[array_offset];
    1498       79700 :                 if (nest_levels>1) {
    1499         162 :                         zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
    1500             : 
    1501         162 :                         if (brk_opline->opcode == ZEND_FREE) {
    1502           7 :                                 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
    1503           5 :                                         zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
    1504             :                                 }
    1505             :                         }
    1506             :                 }
    1507       79700 :                 array_offset = jmp_to->parent;
    1508       79700 :         } while (--nest_levels > 0);
    1509       79538 :         return jmp_to;
    1510             : }
    1511             : 
    1512             : #if ZEND_INTENSIVE_DEBUGGING
    1513             : 
    1514             : #define CHECK_SYMBOL_TABLES()                                                                                                   \
    1515             :         zend_hash_apply(&EG(symbol_table), zend_check_symbol);                      \
    1516             :         if (&EG(symbol_table)!=EX(symbol_table)) {                                                  \
    1517             :                 zend_hash_apply(EX(symbol_table), zend_check_symbol);   \
    1518             :         }
    1519             : 
    1520             : static int zend_check_symbol(zval *pz)
    1521             : {
    1522             :         if (Z_TYPE_P(pz) == IS_INDIRECT) {
    1523             :                 pz = Z_INDIRECT_P(pz);
    1524             :         }
    1525             :         if (Z_TYPE_P(pz) > 10) {
    1526             :                 fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
    1527             : /* See http://support.microsoft.com/kb/190351 */
    1528             : #ifdef PHP_WIN32
    1529             :                 fflush(stderr);
    1530             : #endif
    1531             :         } else if (Z_TYPE_P(pz) == IS_ARRAY) {
    1532             :                 zend_hash_apply(Z_ARRVAL_P(pz), zend_check_symbol);
    1533             :         } else if (Z_TYPE_P(pz) == IS_OBJECT) {
    1534             :                 /* OBJ-TBI - doesn't support new object model! */
    1535             :                 zend_hash_apply(Z_OBJPROP_P(pz), zend_check_symbol);
    1536             :         }
    1537             : 
    1538             :         return 0;
    1539             : }
    1540             : 
    1541             : 
    1542             : #else
    1543             : #define CHECK_SYMBOL_TABLES()
    1544             : #endif
    1545             : 
    1546             : ZEND_API opcode_handler_t *zend_opcode_handlers;
    1547             : 
    1548           0 : ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value)
    1549             : {
    1550           0 :         execute_data->func->internal_function.handler(execute_data, return_value);
    1551           0 : }
    1552             : 
    1553       87831 : ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
    1554             : {
    1555       87831 :         if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
    1556           0 :                 zend_array_destroy(&symbol_table->ht);
    1557           0 :                 efree_size(symbol_table, sizeof(zend_array));
    1558             :         } else {
    1559             :                 /* clean before putting into the cache, since clean
    1560             :                    could call dtors, which could use cached hash */
    1561       87831 :                 zend_symtable_clean(&symbol_table->ht);
    1562       87831 :                 *(++EG(symtable_cache_ptr)) = symbol_table;
    1563             :         }
    1564       87831 : }
    1565             : /* }}} */
    1566             : 
    1567             : static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
    1568             : {
    1569     1965845 :         if (EXPECTED(EX(func)->op_array.last_var > 0)) {
    1570     1761120 :                 zval *cv = EX_VAR_NUM(0);
    1571     1761120 :                 zval *end = cv + EX(func)->op_array.last_var;
    1572             :                 do {
    1573             :                         zval_ptr_dtor(cv);
    1574     9715154 :                         cv++;
    1575     9715154 :                 } while (cv != end);
    1576             :         }
    1577             : }
    1578             : /* }}} */
    1579             : 
    1580          84 : void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
    1581             : {
    1582             :         i_free_compiled_variables(execute_data);
    1583          84 : }
    1584             : /* }}} */
    1585             : 
    1586             : /*
    1587             :  * Stack Frame Layout (the whole stack frame is allocated at once)
    1588             :  * ==================
    1589             :  *
    1590             :  *                             +========================================+
    1591             :  * EG(current_execute_data) -> | zend_execute_data                      |
    1592             :  *                             +----------------------------------------+
    1593             :  *     EX_CV_NUM(0) ---------> | VAR[0] = ARG[1]                        |
    1594             :  *                             | ...                                    |
    1595             :  *                             | VAR[op_array->num_args-1] = ARG[N]     |
    1596             :  *                             | ...                                    |
    1597             :  *                             | VAR[op_array->last_var-1]              |
    1598             :  *                             | VAR[op_array->last_var] = TMP[0]       |
    1599             :  *                             | ...                                    |
    1600             :  *                             | VAR[op_array->last_var+op_array->T-1]  |
    1601             :  *                             | ARG[N+1] (extra_args)                  |
    1602             :  *                             | ...                                    |
    1603             :  *                             +----------------------------------------+
    1604             :  */
    1605             : 
    1606             : static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1607             : {
    1608             :         uint32_t first_extra_arg, num_args;
    1609             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1610             : 
    1611     1527753 :         EX(opline) = op_array->opcodes;
    1612     1527753 :         EX(call) = NULL;
    1613     1527753 :         EX(return_value) = return_value;
    1614             : 
    1615             :         /* Handle arguments */
    1616     1527753 :         first_extra_arg = op_array->num_args;
    1617     1527753 :         num_args = EX_NUM_ARGS();
    1618     1527753 :         if (UNEXPECTED(num_args > first_extra_arg)) {
    1619             :                 zval *end, *src, *dst;
    1620          97 :                 uint32_t type_flags = 0;
    1621             : 
    1622          97 :                 if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1623             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1624          94 :                         EX(opline) += first_extra_arg;
    1625             :                 }
    1626             : 
    1627             :                 /* move extra args into separate array after all CV and TMP vars */
    1628          97 :                 end = EX_VAR_NUM(first_extra_arg - 1);
    1629          97 :                 src = end + (num_args - first_extra_arg);
    1630          97 :                 dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    1631          97 :                 if (EXPECTED(src != dst)) {
    1632             :                         do {
    1633       20173 :                                 type_flags |= Z_TYPE_INFO_P(src);
    1634       20173 :                                 ZVAL_COPY_VALUE(dst, src);
    1635       20173 :                                 ZVAL_UNDEF(src);
    1636       20173 :                                 src--;
    1637       20173 :                                 dst--;
    1638       20173 :                         } while (src != end);
    1639             :                 } else {
    1640             :                         do {
    1641         326 :                                 type_flags |= Z_TYPE_INFO_P(src);
    1642         326 :                                 src--;
    1643         326 :                         } while (src != end);
    1644             :                 }
    1645          97 :                 ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
    1646     1527656 :         } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1647             :                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1648     1439643 :                 EX(opline) += num_args;
    1649             :         }
    1650             : 
    1651             :         /* Initialize CV variables (skip arguments) */
    1652     1527753 :         if (EXPECTED((int)num_args < op_array->last_var)) {
    1653      769405 :                 zval *var = EX_VAR_NUM(num_args);
    1654      769405 :                 zval *end = EX_VAR_NUM(op_array->last_var);
    1655             : 
    1656             :                 do {
    1657     4335986 :                         ZVAL_UNDEF(var);
    1658     4335986 :                         var++;
    1659     4335986 :                 } while (var != end);
    1660             :         }
    1661             : 
    1662     1527753 :         if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
    1663       97805 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
    1664       97805 :                 GC_REFCOUNT(Z_OBJ(EX(This)))++;
    1665             :         }
    1666             : 
    1667     1527753 :         if (UNEXPECTED(!op_array->run_time_cache)) {
    1668       15936 :                 op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
    1669             :         }
    1670     1527753 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    1671     1527753 :         EX_LOAD_LITERALS(op_array);
    1672             : 
    1673     1527753 :         EG(current_execute_data) = execute_data;
    1674             : }
    1675             : /* }}} */
    1676             : 
    1677             : static zend_always_inline void i_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1678             : {
    1679             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1680             : 
    1681        9109 :         EX(opline) = op_array->opcodes;
    1682        9109 :         EX(call) = NULL;
    1683        9109 :         EX(return_value) = return_value;
    1684             : 
    1685        9109 :         zend_attach_symbol_table(execute_data);
    1686             : 
    1687        9109 :         if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
    1688           1 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
    1689           1 :                 GC_REFCOUNT(Z_OBJ(EX(This)))++;
    1690             :         }
    1691             : 
    1692        9109 :         if (!op_array->run_time_cache) {
    1693        9109 :                 op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
    1694             :         }
    1695        9109 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    1696        9109 :         EX_LOAD_LITERALS(op_array);
    1697             : 
    1698        9109 :         EG(current_execute_data) = execute_data;
    1699             : }
    1700             : /* }}} */
    1701             : 
    1702             : static zend_always_inline void i_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1703             : {
    1704             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1705             : 
    1706      458794 :         EX(opline) = op_array->opcodes;
    1707      458794 :         EX(call) = NULL;
    1708      458794 :         EX(return_value) = return_value;
    1709             : 
    1710      458794 :         if (UNEXPECTED(EX(symbol_table) != NULL)) {
    1711       20549 :                 zend_attach_symbol_table(execute_data);
    1712             :         } else {
    1713             :                 uint32_t first_extra_arg, num_args;
    1714             : 
    1715             :                 /* Handle arguments */
    1716      438245 :                 first_extra_arg = op_array->num_args;
    1717      438245 :                 num_args = EX_NUM_ARGS();
    1718      438245 :                 if (UNEXPECTED(num_args > first_extra_arg)) {
    1719             :                         zval *end, *src, *dst;
    1720         998 :                         uint32_t type_flags = 0;
    1721             : 
    1722         998 :                         if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1723             :                                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1724         996 :                                 EX(opline) += first_extra_arg;
    1725             :                         }
    1726             : 
    1727             :                         /* move extra args into separate array after all CV and TMP vars */
    1728         998 :                         end = EX_VAR_NUM(first_extra_arg - 1);
    1729         998 :                         src = end + (num_args - first_extra_arg);
    1730         998 :                         dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    1731         998 :                         if (EXPECTED(src != dst)) {
    1732             :                                 do {
    1733        1319 :                                         type_flags |= Z_TYPE_INFO_P(src);
    1734        1319 :                                         ZVAL_COPY_VALUE(dst, src);
    1735        1319 :                                         ZVAL_UNDEF(src);
    1736        1319 :                                         src--;
    1737        1319 :                                         dst--;
    1738        1319 :                                 } while (src != end);
    1739             :                         } else {
    1740             :                                 do {
    1741        1335 :                                         type_flags |= Z_TYPE_INFO_P(src);
    1742        1335 :                                         src--;
    1743        1335 :                                 } while (src != end);
    1744             :                         }
    1745         998 :                         ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
    1746      437247 :                 } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1747             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1748      437230 :                         EX(opline) += num_args;
    1749             :                 }
    1750             : 
    1751             :                 /* Initialize CV variables (skip arguments) */
    1752      438245 :                 if (EXPECTED((int)num_args < op_array->last_var)) {
    1753      201444 :                         zval *var = EX_VAR_NUM(num_args);
    1754      201444 :                         zval *end = EX_VAR_NUM(op_array->last_var);
    1755             : 
    1756             :                         do {
    1757      577834 :                                 ZVAL_UNDEF(var);
    1758      577834 :                                 var++;
    1759      577834 :                         } while (var != end);
    1760             :                 }
    1761             :         }
    1762             : 
    1763      458794 :         if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
    1764       17466 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
    1765       17466 :                 GC_REFCOUNT(Z_OBJ(EX(This)))++;
    1766             :         }
    1767             : 
    1768      458794 :         if (!op_array->run_time_cache) {
    1769       23603 :                 if (op_array->function_name) {
    1770        6108 :                         op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
    1771             :                 } else {
    1772       20549 :                         op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
    1773             :                 }
    1774             :         }
    1775      458794 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    1776      458794 :         EX_LOAD_LITERALS(op_array);
    1777             : 
    1778      458794 :         EG(current_execute_data) = execute_data;
    1779             : }
    1780             : /* }}} */
    1781             : 
    1782          84 : ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data *call, zend_op_array *op_array, zval *return_value) /* {{{ */
    1783             : {
    1784             :         /*
    1785             :          * Normally the execute_data is allocated on the VM stack (because it does
    1786             :          * not actually do any allocation and thus is faster). For generators
    1787             :          * though this behavior would be suboptimal, because the (rather large)
    1788             :          * structure would have to be copied back and forth every time execution is
    1789             :          * suspended or resumed. That's why for generators the execution context
    1790             :          * is allocated using a separate VM stack, thus allowing to save and
    1791             :          * restore it simply by replacing a pointer.
    1792             :          */
    1793             :         zend_execute_data *execute_data;
    1794          84 :         uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
    1795          84 :         size_t stack_size = (ZEND_CALL_FRAME_SLOT + MAX(op_array->last_var + op_array->T, num_args)) * sizeof(zval);
    1796             : 
    1797         168 :         EG(vm_stack) = zend_vm_stack_new_page(
    1798          84 :                 EXPECTED(stack_size < ZEND_VM_STACK_FREE_PAGE_SIZE) ?
    1799             :                         ZEND_VM_STACK_PAGE_SIZE :
    1800           0 :                         ZEND_VM_STACK_PAGE_ALIGNED_SIZE(stack_size),
    1801             :                 NULL);
    1802          84 :         EG(vm_stack_top) = EG(vm_stack)->top;
    1803          84 :         EG(vm_stack_end) = EG(vm_stack)->end;
    1804             : 
    1805         168 :         execute_data = zend_vm_stack_push_call_frame(
    1806             :                 ZEND_CALL_TOP_FUNCTION,
    1807             :                 (zend_function*)op_array,
    1808             :                 num_args,
    1809             :                 call->called_scope,
    1810             :                 Z_OBJ(call->This),
    1811             :                 NULL);
    1812          84 :         EX_NUM_ARGS() = num_args;
    1813             : 
    1814             :         /* copy arguments */
    1815          84 :         if (num_args > 0) {
    1816          25 :                 zval *arg_src = ZEND_CALL_ARG(call, 1);
    1817          25 :                 zval *arg_dst = ZEND_CALL_ARG(execute_data, 1);
    1818             :                 uint32_t i;
    1819             : 
    1820          59 :                 for (i = 0; i < num_args; i++) {
    1821          34 :                         ZVAL_COPY_VALUE(arg_dst + i, arg_src + i);
    1822             :                 }
    1823             :         }
    1824             : 
    1825          84 :         EX(symbol_table) = NULL;
    1826             : 
    1827             :         i_init_func_execute_data(execute_data, op_array, return_value);
    1828             : 
    1829          84 :         return execute_data;
    1830             : }
    1831             : /* }}} */
    1832             : 
    1833      438245 : ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1834             : {
    1835      438245 :         EX(prev_execute_data) = EG(current_execute_data);
    1836             :         i_init_execute_data(execute_data, op_array, return_value);
    1837      438245 : }
    1838             : /* }}} */
    1839             : 
    1840             : static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(const zend_op *opline, zend_execute_data *call) /* {{{ */
    1841             : {
    1842        3443 :         uint32_t arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK;
    1843        6886 :         return ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num);
    1844             : }
    1845             : /* }}} */
    1846             : 
    1847           3 : static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
    1848             : {
    1849             :         zend_execute_data *new_call;
    1850           3 :         int used_stack = (EG(vm_stack_top) - (zval*)call) + additional_args;
    1851             : 
    1852             :         /* copy call frame into new stack segment */
    1853           3 :         new_call = zend_vm_stack_extend(used_stack * sizeof(zval));
    1854           3 :         *new_call = *call;
    1855           3 :         if (passed_args) {
    1856           1 :                 zval *src = ZEND_CALL_ARG(call, 1);
    1857           1 :                 zval *dst = ZEND_CALL_ARG(new_call, 1);
    1858             :                 do {
    1859       10000 :                         ZVAL_COPY_VALUE(dst, src);
    1860       10000 :                         passed_args--;
    1861       10000 :                         src++;
    1862       10000 :                         dst++;
    1863       10000 :                 } while (passed_args);
    1864             :         }
    1865             : 
    1866             :         /* delete old call_frame from previous stack segment */
    1867           3 :         EG(vm_stack)->prev->top = (zval*)call;
    1868             : 
    1869             :         /* delete previous stack segment if it becames empty */
    1870           3 :         if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMETS(EG(vm_stack)->prev))) {
    1871           0 :                 zend_vm_stack r = EG(vm_stack)->prev;
    1872             : 
    1873           0 :                 EG(vm_stack)->prev = r->prev;
    1874           0 :                 efree(r);
    1875             :         }
    1876             : 
    1877           3 :         return new_call;
    1878             : }
    1879             : /* }}} */
    1880             : 
    1881             : static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data **call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
    1882             : {
    1883         204 :         if (EXPECTED(EG(vm_stack_end) - EG(vm_stack_top) > additional_args)) {
    1884         201 :                 EG(vm_stack_top) += additional_args;
    1885             :         } else {
    1886           3 :                 *call = zend_vm_stack_copy_call_frame(*call, passed_args, additional_args);
    1887             :         }
    1888             : }
    1889             : /* }}} */
    1890             : 
    1891             : #define ZEND_VM_NEXT_OPCODE() \
    1892             :         CHECK_SYMBOL_TABLES() \
    1893             :         ZEND_VM_INC_OPCODE(); \
    1894             :         ZEND_VM_CONTINUE()
    1895             : 
    1896             : #define ZEND_VM_SET_OPCODE(new_op) \
    1897             :         CHECK_SYMBOL_TABLES() \
    1898             :         OPLINE = new_op
    1899             : 
    1900             : #define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
    1901             :         ZEND_VM_SET_OPCODE(ZEND_OFFSET_TO_OPLINE(opline, offset))
    1902             : 
    1903             : #define ZEND_VM_JMP(new_op) \
    1904             :         if (EXPECTED(!EG(exception))) { \
    1905             :                 ZEND_VM_SET_OPCODE(new_op); \
    1906             :         } else { \
    1907             :                 LOAD_OPLINE(); \
    1908             :         } \
    1909             :         ZEND_VM_CONTINUE()
    1910             : 
    1911             : #define ZEND_VM_INC_OPCODE() \
    1912             :         OPLINE++
    1913             : 
    1914             : #ifdef __GNUC__
    1915             : # define ZEND_VM_GUARD(name) __asm__("#" #name)
    1916             : #else
    1917             : # define ZEND_VM_GUARD(name)
    1918             : #endif
    1919             : 
    1920             : #include "zend_vm_execute.h"
    1921             : 
    1922           0 : ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
    1923             : {
    1924           0 :         if (opcode != ZEND_USER_OPCODE) {
    1925           0 :                 if (handler == NULL) {
    1926             :                         /* restore the original handler */
    1927           0 :                         zend_user_opcodes[opcode] = opcode;
    1928             :                 } else {
    1929           0 :                         zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
    1930             :                 }
    1931           0 :                 zend_user_opcode_handlers[opcode] = handler;
    1932           0 :                 return SUCCESS;
    1933             :         }
    1934           0 :         return FAILURE;
    1935             : }
    1936             : 
    1937           0 : ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
    1938             : {
    1939           0 :         return zend_user_opcode_handlers[opcode];
    1940             : }
    1941             : 
    1942           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) {
    1943           0 :         return get_zval_ptr(op_type, *node, execute_data, should_free, type);
    1944             : }
    1945             : 
    1946             : /*
    1947             :  * Local variables:
    1948             :  * tab-width: 4
    1949             :  * c-basic-offset: 4
    1950             :  * indent-tabs-mode: t
    1951             :  * End:
    1952             :  */

Generated by: LCOV version 1.10

Generated at Sun, 18 Jan 2015 09:00:35 +0000 (6 days ago)

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