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: 720 825 87.3 %
Date: 2015-03-01 Functions: 33 41 80.5 %
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       20924 :         zend_vm_stack page = (zend_vm_stack)emalloc(size);
     138             : 
     139       20924 :         page->top = ZEND_VM_STACK_ELEMETS(page);
     140       20924 :         page->end = (zval*)((char*)page + size);
     141       20924 :         page->prev = prev;
     142       20924 :         return page;
     143             : }
     144             : 
     145       20828 : ZEND_API void zend_vm_stack_init(void)
     146             : {
     147       20828 :         EG(vm_stack) = zend_vm_stack_new_page(ZEND_VM_STACK_PAGE_SIZE, NULL);
     148       20828 :         EG(vm_stack)->top++;
     149       20828 :         EG(vm_stack_top) = EG(vm_stack)->top;
     150       20828 :         EG(vm_stack_end) = EG(vm_stack)->end;
     151       20828 : }
     152             : 
     153       20864 : ZEND_API void zend_vm_stack_destroy(void)
     154             : {
     155       20864 :         zend_vm_stack stack = EG(vm_stack);
     156             : 
     157       62592 :         while (stack != NULL) {
     158       20864 :                 zend_vm_stack p = stack->prev;
     159       20864 :                 efree(stack);
     160       20864 :                 stack = p;
     161             :         }
     162       20864 : }
     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     4467166 :         zval *ret = EX_VAR(var);
     189     4467166 :         *should_free = ret;
     190             : 
     191             :         ZEND_ASSERT(Z_TYPE_P(ret) != IS_REFERENCE);
     192             : 
     193     4467166 :         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    39478841 :         zval *ret = EX_VAR(var);
     199             : 
     200    39478841 :         *should_free = ret;
     201    39478841 :         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    11652790 :         zval *ret = EX_VAR(var);
     207             : 
     208    11652790 :         *should_free = ret;
     209    11652790 :         ZVAL_DEREF(ret);
     210    11652790 :         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       38576 :         ZVAL_NULL(ptr);
     265       38576 :         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     1073903 :         zval *ret = EX_VAR(var);
     271             : 
     272     1073903 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     273           0 :                 return _get_zval_cv_lookup(ret, var, type, execute_data);
     274             :         }
     275     1073903 :         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     2048578 :         zval *ret = EX_VAR(var);
     281             : 
     282     2048578 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     283          10 :                 return _get_zval_cv_lookup(ret, var, type, execute_data);
     284             :         }
     285     2048568 :         ZVAL_DEREF(ret);
     286     2048568 :         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    45573867 :         zval *ret = EX_VAR(var);
     292             : 
     293    45573867 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     294         586 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data);
     295             :         }
     296    45573281 :         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     5110165 :         zval *ret = EX_VAR(var);
     302             : 
     303     5110165 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     304          11 :                 return _get_zval_cv_lookup_BP_VAR_R(ret, var, execute_data);
     305             :         }
     306     5110154 :         ZVAL_DEREF(ret);
     307     5110154 :         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       21988 :         zval *ret = EX_VAR(var);
     313             : 
     314       21988 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     315           0 :                 return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var, execute_data);
     316             :         }
     317       21988 :         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      460431 :         zval *ret = EX_VAR(var);
     334             : 
     335      460431 :         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     9174999 :         zval *ret = EX_VAR(var);
     349             : 
     350     9174999 :         if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
     351           3 :                 return _get_zval_cv_lookup_BP_VAR_RW(ret, var, execute_data);
     352             :         }
     353     9174996 :         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     3968881 :         zval *ret = EX_VAR(var);
     370             : 
     371     3968881 :         if (Z_TYPE_P(ret) == IS_UNDEF) {
     372       38576 :                 return _get_zval_cv_lookup_BP_VAR_W(ret, var, execute_data);
     373             :         }
     374     3930305 :         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    20788984 :         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     1075147 :         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     1073990 :                 *should_free = NULL;
     404     1073990 :                 if (op_type == IS_CONST) {
     405          87 :                         return EX_CONSTANT(node);
     406             :                 } else {
     407             :                         ZEND_ASSERT(op_type == IS_CV);
     408     2147806 :                         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     3034210 :         if (op_type & (IS_TMP_VAR|IS_VAR)) {
     416      315686 :                 if (op_type == IS_TMP_VAR) {
     417      213534 :                         return _get_zval_ptr_tmp(node.var, execute_data, should_free);
     418             :                 } else {
     419             :                         ZEND_ASSERT(op_type == IS_VAR);
     420      417838 :                         return _get_zval_ptr_var_deref(node.var, execute_data, should_free);
     421             :                 }
     422             :         } else {
     423     2718524 :                 *should_free = NULL;
     424     2718524 :                 if (op_type == IS_CONST) {
     425      669946 :                         return EX_CONSTANT(node);
     426             :                 } else {
     427             :                         ZEND_ASSERT(op_type == IS_CV);
     428     4097156 :                         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      699833 :         zval *ret = EX_VAR(var);
     436             : 
     437      699833 :         if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
     438      698547 :                 *should_free = NULL;
     439      698547 :                 ret = Z_INDIRECT_P(ret);
     440        1286 :         } else if (!Z_REFCOUNTED_P(ret)) {
     441          71 :                 *should_free = ret; /* immutable array may be converted to regular */
     442        1215 :         } else if (Z_REFCOUNT_P(ret) == 1) {
     443         107 :                 *should_free = ret;
     444             :         } else {
     445        1108 :                 *should_free = NULL;
     446             :                 Z_DELREF_P(ret);
     447             :         }
     448      699833 :         return ret;
     449             : }
     450             : 
     451             : 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)
     452             : {
     453             :         if (op_type == IS_CV) {
     454             :                 *should_free = NULL;
     455             :                 return _get_zval_ptr_cv(execute_data, node.var, type);
     456             :         } else /* if (op_type == IS_VAR) */ {
     457             :                 ZEND_ASSERT(op_type == IS_VAR);
     458             :                 return _get_zval_ptr_ptr_var(node.var, execute_data, should_free);
     459             :         }
     460             : }
     461             : 
     462             : static zend_always_inline zval *_get_obj_zval_ptr_unused(zend_execute_data *execute_data)
     463             : {
     464      225885 :         if (EXPECTED(Z_OBJ(EX(This)) != NULL)) {
     465      225881 :                 return &EX(This);
     466             :         } else {
     467           4 :                 zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     468             :                 return NULL;
     469             :         }
     470             : }
     471             : 
     472             : 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)
     473             : {
     474             :         if (op_type == IS_UNUSED) {
     475             :                 if (EXPECTED(Z_OBJ(EX(This)) != NULL)) {
     476             :                         *should_free = NULL;
     477             :                         return &EX(This);
     478             :                 } else {
     479             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     480             :                 }
     481             :         }
     482             :         return get_zval_ptr(op_type, op, execute_data, should_free, type);
     483             : }
     484             : 
     485             : 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)
     486             : {
     487             :         if (op_type == IS_UNUSED) {
     488             :                 if (EXPECTED(Z_OBJ(EX(This)) != NULL)) {
     489             :                         *should_free = NULL;
     490             :                         return &EX(This);
     491             :                 } else {
     492             :                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");
     493             :                 }
     494             :         }
     495             :         return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type);
     496             : }
     497             : 
     498      952450 : static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *value_ptr)
     499             : {
     500      952450 :         if (EXPECTED(variable_ptr != value_ptr)) {
     501             :                 zend_reference *ref;
     502     1903746 :                 ZVAL_MAKE_REF(value_ptr);
     503             :                 Z_ADDREF_P(value_ptr);
     504      951873 :                 ref = Z_REF_P(value_ptr);
     505             : 
     506             :                 zval_ptr_dtor(variable_ptr);
     507      951873 :                 ZVAL_REF(variable_ptr, ref);
     508             :         } else {
     509        1154 :                 ZVAL_MAKE_REF(variable_ptr);
     510             :         }
     511      952450 : }
     512             : 
     513             : /* this should modify object only if it's empty */
     514          21 : static inline int make_real_object(zval **object_ptr)
     515             : {
     516          21 :         zval *object = *object_ptr;
     517             : 
     518          21 :         ZVAL_DEREF(object);
     519          21 :         if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     520          42 :                 if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE)
     521          22 :                         || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
     522             :                         zval_ptr_dtor_nogc(object);
     523          11 :                         object_init(object);
     524          11 :                         zend_error(E_WARNING, "Creating default object from empty value");
     525             :                 } else {
     526           7 :                         return 0;
     527             :                 }
     528             :         }
     529          14 :         *object_ptr = object;
     530          14 :         return 1;
     531             : }
     532             : 
     533        1160 : ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
     534             : {
     535             :         zend_string *key;
     536             :         ALLOCA_FLAG(use_heap);
     537             : 
     538        1160 :         STR_ALLOCA_INIT(key, cur_arg_info->class_name, strlen(cur_arg_info->class_name), use_heap);
     539        1160 :         *pce = zend_fetch_class(key, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
     540        1160 :         STR_ALLOCA_FREE(key, use_heap);
     541             : 
     542        1160 :         *class_name = (*pce) ? (*pce)->name->val : (char*)cur_arg_info->class_name;
     543        1160 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     544         472 :                 return "implement interface ";
     545             :         } else {
     546         688 :                 return "be an instance of ";
     547             :         }
     548             : }
     549             : 
     550       87917 : ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
     551             : {
     552       87917 :         *pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
     553             : 
     554       87917 :         *class_name = (*pce) ? (*pce)->name->val : cur_arg_info->class_name->val;
     555       87917 :         if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {
     556         175 :                 return "implement interface ";
     557             :         } else {
     558       87742 :                 return "be an instance of ";
     559             :         }
     560             : }
     561             : 
     562         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)
     563             : {
     564         225 :         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
     565         225 :         const char *fname = zf->common.function_name->val;
     566             :         const char *fsep;
     567             :         const char *fclass;
     568             :         zval old_arg;
     569             : 
     570         225 :         if (zf->common.scope) {
     571          30 :                 fsep =  "::";
     572          30 :                 fclass = zf->common.scope->name->val;
     573             :         } else {
     574         195 :                 fsep =  "";
     575         195 :                 fclass = "";
     576             :         }
     577             : 
     578         225 :         if (zf->common.type == ZEND_USER_FUNCTION) {
     579          30 :                 if (arg) {
     580          25 :                         ZVAL_COPY_VALUE(&old_arg, arg);
     581          25 :                         ZVAL_UNDEF(arg);
     582             :                 }
     583             : 
     584          39 :                 if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     585          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);
     586             :                 } else {
     587           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);
     588             :                 }
     589             : 
     590           9 :                 if (arg) {
     591           8 :                         ZVAL_COPY_VALUE(arg, &old_arg);
     592             :                 }
     593             :         } else {
     594         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);
     595             :         }
     596         163 : }
     597             : 
     598           3 : static int is_null_constant(zval *default_value)
     599             : {
     600           3 :         if (Z_CONSTANT_P(default_value)) {
     601             :                 zval constant;
     602             : 
     603           3 :                 ZVAL_COPY_VALUE(&constant, default_value);
     604           3 :                 zval_update_constant(&constant, 0);
     605           3 :                 if (Z_TYPE(constant) == IS_NULL) {
     606           2 :                         return 1;
     607             :                 }
     608             :                 zval_dtor(&constant);
     609             :         }
     610           1 :         return 0;
     611             : }
     612             : 
     613        4331 : static void zend_verify_internal_arg_type(zend_function *zf, uint32_t arg_num, zval *arg)
     614             : {
     615             :         zend_internal_arg_info *cur_arg_info;
     616             :         char *need_msg;
     617             :         zend_class_entry *ce;
     618             : 
     619        4331 :         if (EXPECTED(arg_num <= zf->internal_function.num_args)) {
     620        4298 :                 cur_arg_info = &zf->internal_function.arg_info[arg_num-1];
     621          33 :         } else if (zf->internal_function.fn_flags & ZEND_ACC_VARIADIC) {
     622           0 :                 cur_arg_info = &zf->internal_function.arg_info[zf->internal_function.num_args];
     623             :         } else {
     624          33 :                 return;
     625             :         }
     626             : 
     627        4298 :         if (cur_arg_info->class_name) {
     628             :                 char *class_name;
     629             : 
     630        1165 :                 ZVAL_DEREF(arg);
     631        1165 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     632        1042 :                         need_msg = zend_verify_internal_arg_class_kind((zend_internal_arg_info*)cur_arg_info, &class_name, &ce);
     633        1042 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce)) {
     634          70 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg);
     635             :                         }
     636         123 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
     637         118 :                         need_msg = zend_verify_internal_arg_class_kind((zend_internal_arg_info*)cur_arg_info, &class_name, &ce);
     638         118 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg);
     639             :                 }
     640        3133 :         } else if (cur_arg_info->type_hint) {
     641         324 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     642         324 :                         ZVAL_DEREF(arg);
     643         344 :                         if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     644           7 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg);
     645             :                         }
     646           0 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     647           0 :                         if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
     648           0 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg);
     649             :                         }
     650             : #if ZEND_DEBUG
     651             :                 } else {
     652             :                         zend_error(E_ERROR, "Unknown typehint");
     653             : #endif
     654             :                 }
     655             :         }
     656             : }
     657             : 
     658       88291 : static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *default_value)
     659             : {
     660             :         zend_arg_info *cur_arg_info;
     661             :         char *need_msg;
     662             :         zend_class_entry *ce;
     663             : 
     664       88291 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     665       88282 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     666           9 :         } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
     667           9 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args];
     668             :         } else {
     669           0 :                 return;
     670             :         }
     671             : 
     672       88291 :         if (cur_arg_info->class_name) {
     673             :                 char *class_name;
     674             : 
     675       87935 :                 ZVAL_DEREF(arg);
     676       87935 :                 if (Z_TYPE_P(arg) == IS_OBJECT) {
     677       87891 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce);
     678       87891 :                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce)) {
     679          12 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg);
     680             :                         }
     681          44 :                 } else if (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value)))) {
     682           7 :                         need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce);
     683           7 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg);
     684             :                 }
     685         356 :         } else if (cur_arg_info->type_hint) {
     686         177 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     687         169 :                         ZVAL_DEREF(arg);
     688         180 :                         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))))) {
     689           6 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg);
     690             :                         }
     691           8 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     692           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))))) {
     693           0 :                                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg);
     694             :                         }
     695             : #if ZEND_DEBUG
     696             :                 } else {
     697             :                         zend_error(E_ERROR, "Unknown typehint");
     698             : #endif
     699             :                 }
     700             :         }
     701             : }
     702             : 
     703           5 : static inline int zend_verify_missing_arg_type(zend_function *zf, uint32_t arg_num)
     704             : {
     705             :         zend_arg_info *cur_arg_info;
     706             :         char *need_msg;
     707             :         zend_class_entry *ce;
     708             : 
     709           5 :         if (EXPECTED(arg_num <= zf->common.num_args)) {
     710           5 :                 cur_arg_info = &zf->common.arg_info[arg_num-1];
     711           0 :         } else if (zf->common.fn_flags & ZEND_ACC_VARIADIC) {
     712           0 :                 cur_arg_info = &zf->common.arg_info[zf->common.num_args];
     713             :         } else {
     714           0 :                 return 1;
     715             :         }
     716             : 
     717           5 :         if (cur_arg_info->class_name) {
     718             :                 char *class_name;
     719             : 
     720           2 :                 need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce);
     721           2 :                 zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "", NULL);
     722           0 :                 return 0;
     723           3 :         } else if (cur_arg_info->type_hint) {
     724           3 :                 if (cur_arg_info->type_hint == IS_ARRAY) {
     725           2 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "", NULL);
     726           1 :                 } else if (cur_arg_info->type_hint == IS_CALLABLE) {
     727           1 :                         zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "", NULL);
     728             : #if ZEND_DEBUG
     729             :                 } else {
     730             :                         zend_error(E_ERROR, "Unknown typehint");
     731             : #endif
     732             :                 }
     733           1 :                 return 0;
     734             :         }
     735           0 :         return 1;
     736             : }
     737             : 
     738          75 : static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t arg_num)
     739             : {
     740          76 :         if (EXPECTED(!(EX(func)->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS)) ||
     741           5 :             zend_verify_missing_arg_type(EX(func), arg_num)) {
     742          70 :                 const char *class_name = EX(func)->common.scope ? EX(func)->common.scope->name->val : "";
     743          70 :                 const char *space = EX(func)->common.scope ? "::" : "";
     744          70 :                 const char *func_name = EX(func)->common.function_name ? EX(func)->common.function_name->val : "main";
     745          70 :                 zend_execute_data *ptr = EX(prev_execute_data);
     746             : 
     747          85 :                 if (ptr && ptr->func && ZEND_USER_CODE(ptr->func->common.type)) {
     748          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);
     749             :                 } else {
     750          55 :                         zend_error(E_WARNING, "Missing argument %u for %s%s%s()", arg_num, class_name, space, func_name);
     751             :                 }
     752             :         }
     753          71 : }
     754             : 
     755          10 : ZEND_API void zend_verify_return_error(int error_type, const zend_function *zf, const char *need_msg, const char *need_kind, const char *returned_msg, const char *returned_kind)
     756             : {
     757          10 :         const char *fname = zf->common.function_name->val;
     758             :         const char *fsep;
     759             :         const char *fclass;
     760             : 
     761          10 :         if (zf->common.scope) {
     762           2 :                 fsep =  "::";
     763           2 :                 fclass = zf->common.scope->name->val;
     764             :         } else {
     765           8 :                 fsep =  "";
     766           8 :                 fclass = "";
     767             :         }
     768             : 
     769          10 :         zend_error(error_type,
     770             :                 "Return value of %s%s%s() must %s%s, %s%s returned",
     771             :                 fclass, fsep, fname, need_msg, need_kind, returned_msg, returned_kind);
     772           0 : }
     773             : 
     774             : #if ZEND_DEBUG
     775             : static int zend_verify_internal_return_type(zend_function *zf, zval *ret)
     776             : {
     777             :         zend_arg_info *ret_info = zf->common.arg_info - 1;
     778             :         char *need_msg;
     779             :         zend_class_entry *ce;
     780             : 
     781             :         if (ret_info->class_name) {
     782             :                 char *class_name;
     783             : 
     784             :                 if (Z_TYPE_P(ret) == IS_OBJECT) {
     785             :                         need_msg = zend_verify_internal_arg_class_kind((zend_internal_arg_info *)ret_info, &class_name, &ce);
     786             :                         if (!ce || !instanceof_function(Z_OBJCE_P(ret), ce)) {
     787             :                                 zend_verify_return_error(E_CORE_ERROR, zf, need_msg, class_name, "instance of ", Z_OBJCE_P(ret)->name->val);
     788             :                                 return 0;
     789             :                         }
     790             :                 } else if (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null) {
     791             :                         need_msg = zend_verify_internal_arg_class_kind((zend_internal_arg_info *)ret_info, &class_name, &ce);
     792             :                         zend_verify_return_error(E_CORE_ERROR, zf, need_msg, class_name, zend_zval_type_name(ret), "");
     793             :                         return 0;
     794             :                 }
     795             :         } else if (ret_info->type_hint) {
     796             :                 if (ret_info->type_hint == IS_ARRAY) {
     797             :                         if (Z_TYPE_P(ret) != IS_ARRAY && (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null)) {
     798             :                                 zend_verify_return_error(E_CORE_ERROR, zf, "be of the type array", "", zend_zval_type_name(ret), "");
     799             :                                 return 0;
     800             :                         }
     801             :                 } else if (ret_info->type_hint == IS_CALLABLE) {
     802             :                         if (!zend_is_callable(ret, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null)) {
     803             :                                 zend_verify_return_error(E_CORE_ERROR, zf, "be callable", "", zend_zval_type_name(ret), "");
     804             :                                 return 0;
     805             :                         }
     806             : #if ZEND_DEBUG
     807             :                 } else {
     808             :                         zend_error(E_CORE_ERROR, "Unknown typehint");
     809             :                         return 0;
     810             : #endif
     811             :                 }
     812             :         }
     813             :         return 1;
     814             : }
     815             : #endif
     816             : 
     817          26 : static void zend_verify_return_type(zend_function *zf, zval *ret)
     818             : {
     819          26 :         zend_arg_info *ret_info = zf->common.arg_info - 1;
     820             :         char *need_msg;
     821             :         zend_class_entry *ce;
     822             : 
     823          26 :         if (ret_info->class_name) {
     824             :                 char *class_name;
     825             : 
     826          17 :                 if (Z_TYPE_P(ret) == IS_OBJECT) {
     827          15 :                         need_msg = zend_verify_arg_class_kind(ret_info, &class_name, &ce);
     828          15 :                         if (!ce || !instanceof_function(Z_OBJCE_P(ret), ce)) {
     829           1 :                                 zend_verify_return_error(E_RECOVERABLE_ERROR, zf, need_msg, class_name, "instance of ", Z_OBJCE_P(ret)->name->val);
     830             :                         }
     831           2 :                 } else if (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null) {
     832           2 :                         need_msg = zend_verify_arg_class_kind(ret_info, &class_name, &ce);
     833           2 :                         zend_verify_return_error(E_RECOVERABLE_ERROR, zf, need_msg, class_name, zend_zval_type_name(ret), "");
     834             :                 }
     835           9 :         } else if (ret_info->type_hint) {
     836           9 :                 if (ret_info->type_hint == IS_ARRAY) {
     837          12 :                         if (Z_TYPE_P(ret) != IS_ARRAY && (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null)) {
     838           6 :                                 zend_verify_return_error(E_RECOVERABLE_ERROR, zf, "be of the type array", "", zend_zval_type_name(ret), "");
     839             :                         }
     840           3 :                 } else if (ret_info->type_hint == IS_CALLABLE) {
     841           3 :                         if (!zend_is_callable(ret, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(ret) != IS_NULL || !ret_info->allow_null)) {
     842           0 :                                 zend_verify_return_error(E_RECOVERABLE_ERROR, zf, "be callable", "", zend_zval_type_name(ret), "");
     843             :                         }
     844             : #if ZEND_DEBUG
     845             :                 } else {
     846             :                         zend_error(E_ERROR, "Unknown typehint");
     847             : #endif
     848             :                 }
     849             :         }
     850          17 : }
     851             : 
     852           1 : static inline int zend_verify_missing_return_type(zend_function *zf)
     853             : {
     854           1 :         zend_arg_info *ret_info = zf->common.arg_info - 1;
     855             :         char *need_msg;
     856             :         zend_class_entry *ce;
     857             : 
     858           1 :         if (ret_info->class_name) {
     859             :                 char *class_name;
     860             : 
     861           0 :                 need_msg = zend_verify_arg_class_kind(ret_info, &class_name, &ce);
     862           0 :                 zend_verify_return_error(E_RECOVERABLE_ERROR, zf, need_msg, class_name, "none", "");
     863           0 :                 return 0;
     864           1 :         } else if (ret_info->type_hint) {
     865           1 :                 if (ret_info->type_hint == IS_ARRAY) {
     866           1 :                         zend_verify_return_error(E_RECOVERABLE_ERROR, zf, "be of the type array", "", "none", "");
     867           0 :                 } else if (ret_info->type_hint == IS_CALLABLE) {
     868           0 :                         zend_verify_return_error(E_RECOVERABLE_ERROR, zf, "be callable", "", "none", "");
     869             : #if ZEND_DEBUG
     870             :                 } else {
     871             :                         zend_error(E_ERROR, "Unknown typehint");
     872             : #endif
     873             :                 }
     874           0 :                 return 0;
     875             :         }
     876           0 :         return 1;
     877             : }
     878             : 
     879             : 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)
     880             : {
     881             :         zend_free_op free_value;
     882      113916 :         zval *value = get_zval_ptr_deref(value_type, value_op, execute_data, &free_value, BP_VAR_R);
     883             :         zval tmp;
     884             : 
     885      125887 :         if (object_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
     886             :                 do {
     887       10095 :                         if (object_op_type == IS_VAR && UNEXPECTED(object == &EG(error_zval))) {
     888           0 :                                 if (retval) {
     889           0 :                                         ZVAL_NULL(retval);
     890             :                                 }
     891           0 :                                 FREE_OP(free_value);
     892             :                                 return;
     893             :                         }
     894       10095 :                         if (Z_ISREF_P(object)) {
     895       10067 :                                 object = Z_REFVAL_P(object);
     896       10067 :                                 if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) {
     897             :                                         break;
     898             :                                 }
     899             :                         }
     900          33 :                         if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE ||
     901             :                         (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
     902             :                                 zend_object *obj;
     903             : 
     904             :                                 zval_ptr_dtor(object);
     905          24 :                                 object_init(object);
     906             :                                 Z_ADDREF_P(object);
     907          24 :                                 obj = Z_OBJ_P(object);
     908          24 :                                 zend_error(E_WARNING, "Creating default object from empty value");
     909          24 :                                 if (GC_REFCOUNT(obj) == 1) {
     910             :                                         /* the enclosing container was deleted, obj is unreferenced */
     911           1 :                                         if (retval) {
     912           1 :                                                 ZVAL_NULL(retval);
     913             :                                         }
     914           1 :                                         FREE_OP(free_value);
     915             :                                         OBJ_RELEASE(obj);
     916             :                                         return;
     917             :                                 }
     918             :                                 Z_DELREF_P(object);
     919             :                         } else {
     920           4 :                                 zend_error(E_WARNING, "Attempt to assign property of non-object");
     921           4 :                                 if (retval) {
     922           0 :                                         ZVAL_NULL(retval);
     923             :                                 }
     924           4 :                                 FREE_OP(free_value);
     925             :                                 return;
     926             :                         }
     927             :                 } while (0);
     928             :         }
     929             : 
     930      217674 :         if (property_op_type == IS_CONST &&
     931      103763 :                 EXPECTED(Z_OBJCE_P(object) == CACHED_PTR_EX(cache_slot))) {
     932      101494 :                 uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
     933      101494 :                 zend_object *zobj = Z_OBJ_P(object);
     934             :                 zval *property;
     935             : 
     936      101494 :                 if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
     937       90471 :                         property = OBJ_PROP(zobj, prop_offset);
     938       90471 :                         if (Z_TYPE_P(property) != IS_UNDEF) {
     939             : fast_assign:
     940      181282 :                                 value = zend_assign_to_variable(property, value, value_type);
     941       90641 :                                 if (retval && !EG(exception)) {
     942           0 :                                         ZVAL_COPY(retval, value);
     943             :                                 }
     944       90641 :                                 if (value_type == IS_VAR) {
     945         169 :                                         FREE_OP(free_value);
     946             :                                 }
     947             :                                 return;
     948             :                         }
     949             :                 } else {
     950       11023 :                         if (EXPECTED(zobj->properties != NULL)) {
     951         672 :                                 property = zend_hash_find(zobj->properties, Z_STR_P(property_name));
     952         672 :                                 if (property) {
     953             :                                         goto fast_assign;
     954             :                                 }
     955             :                         }
     956             : 
     957       10851 :                         if (!zobj->ce->__set) {
     958       10846 :                                 if (EXPECTED(zobj->properties == NULL)) {
     959       10346 :                                         rebuild_object_properties(zobj);
     960             :                                 }
     961             :                                 /* separate our value if necessary */
     962       10846 :                                 if (value_type == IS_CONST) {
     963       10281 :                                         if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
     964           2 :                                                 ZVAL_COPY_VALUE(&tmp, value);
     965           2 :                                                 zval_copy_ctor_func(&tmp);
     966           2 :                                                 value = &tmp;
     967             :                                         }
     968         939 :                                 } else if (value_type != IS_TMP_VAR &&
     969         374 :                                            Z_REFCOUNTED_P(value)) {
     970             :                                         Z_ADDREF_P(value);
     971             :                                 }
     972       10846 :                                 zend_hash_add_new(zobj->properties, Z_STR_P(property_name), value);
     973       10846 :                                 if (retval && !EG(exception)) {
     974           0 :                                         ZVAL_COPY(retval, value);
     975             :                                 }
     976       10846 :                                 if (value_type == IS_VAR) {
     977         198 :                                         FREE_OP(free_value);
     978             :                                 }
     979             :                                 return;
     980             :                         }
     981             :         }
     982             :         }
     983             : 
     984       12424 :         if (!Z_OBJ_HT_P(object)->write_property) {
     985           0 :                 zend_error(E_WARNING, "Attempt to assign property of non-object");
     986           0 :                 if (retval) {
     987           0 :                         ZVAL_NULL(retval);
     988             :                 }
     989           0 :                 FREE_OP(free_value);
     990             :                 return;
     991             :         }
     992             : 
     993             :         /* separate our value if necessary */
     994       12424 :         if (value_type == IS_CONST) {
     995        1185 :                 if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
     996          41 :                         ZVAL_COPY_VALUE(&tmp, value);
     997          41 :                         zval_copy_ctor_func(&tmp);
     998          41 :                         value = &tmp;
     999             :                 }
    1000       22322 :         } else if (value_type != IS_TMP_VAR &&
    1001       11083 :                    Z_REFCOUNTED_P(value)) {
    1002             :                 Z_ADDREF_P(value);
    1003             :         }
    1004             : 
    1005       12424 :         Z_OBJ_HT_P(object)->write_property(object, property_name, value, cache_slot);
    1006             : 
    1007       12416 :         if (retval && !EG(exception)) {
    1008          25 :                 ZVAL_COPY(retval, value);
    1009             :         }
    1010             :         zval_ptr_dtor(value);
    1011       12416 :         if (value_type == IS_VAR) {
    1012         260 :                 FREE_OP(free_value);
    1013             :         }
    1014             : }
    1015             : 
    1016             : 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)
    1017             : {
    1018             :         zend_free_op free_value;
    1019        1556 :         zval *value = get_zval_ptr_deref(value_type, value_op, execute_data, &free_value, BP_VAR_R);
    1020             :         zval tmp;
    1021             : 
    1022             :         /* Note:  property_name in this case is really the array index! */
    1023        1556 :         if (!Z_OBJ_HT_P(object)->write_dimension) {
    1024           0 :                 zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1025             :         }
    1026             : 
    1027             :         /* separate our value if necessary */
    1028        1556 :         if (value_type == IS_CONST) {
    1029        1447 :                 if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) {
    1030           1 :                         ZVAL_COPY_VALUE(&tmp, value);
    1031           1 :                         zval_copy_ctor_func(&tmp);
    1032           1 :                         value = &tmp;
    1033             :                 }
    1034         201 :         } else if (value_type != IS_TMP_VAR &&
    1035          92 :                    Z_REFCOUNTED_P(value)) {
    1036             :                 Z_ADDREF_P(value);
    1037             :         }
    1038             : 
    1039        1556 :         Z_OBJ_HT_P(object)->write_dimension(object, property_name, value);
    1040             : 
    1041        1554 :         if (retval && !EG(exception)) {
    1042           5 :                 ZVAL_COPY(retval, value);
    1043             :         }
    1044             :         zval_ptr_dtor(value);
    1045        1554 :         if (value_type == IS_VAR) {
    1046          14 :                 FREE_OP(free_value);
    1047             :         }
    1048             : }
    1049             : 
    1050          12 : 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))
    1051             : {
    1052             :         zval *z;
    1053             :         zval rv, res;
    1054             : 
    1055          36 :         if (Z_OBJ_HT_P(object)->read_dimension &&
    1056          12 :                 (z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) {
    1057             : 
    1058          12 :                 if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
    1059             :                         zval rv;
    1060           4 :                         zval *value = Z_OBJ_HT_P(z)->get(z, &rv);
    1061             : 
    1062           4 :                         if (Z_REFCOUNT_P(z) == 0) {
    1063           0 :                                 zend_objects_store_del(Z_OBJ_P(z));
    1064             :                         }
    1065           4 :                         ZVAL_COPY_VALUE(z, value);
    1066             :                 }
    1067          12 :                 binary_op(&res, Z_ISREF_P(z) ? Z_REFVAL_P(z) : z, value);
    1068          12 :                 Z_OBJ_HT_P(object)->write_dimension(object, property, &res);
    1069          12 :                 if (z == &rv) {
    1070             :                         zval_ptr_dtor(&rv);
    1071             :                 }
    1072          12 :                 if (retval) {
    1073           0 :                         ZVAL_COPY(retval, &res);
    1074             :                 }
    1075             :                 zval_ptr_dtor(&res);
    1076             :         } else {
    1077           0 :                 zend_error(E_WARNING, "Attempt to assign property of non-object");
    1078           0 :                 if (retval) {
    1079           0 :                         ZVAL_NULL(retval);
    1080             :                 }
    1081             :         }
    1082          12 : }
    1083             : 
    1084         145 : static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *value, zval *result)
    1085             : {
    1086             :         zend_string *old_str;
    1087             : 
    1088         145 :         if (offset < 0) {
    1089           1 :                 zend_error(E_WARNING, "Illegal string offset:  " ZEND_LONG_FMT, offset);
    1090           1 :                 zend_string_release(Z_STR_P(str));
    1091           1 :                 if (result) {
    1092           0 :                         ZVAL_NULL(result);
    1093             :                 }
    1094           1 :                 return;
    1095             :         }
    1096             : 
    1097         144 :         old_str = Z_STR_P(str);
    1098         144 :         if ((size_t)offset >= Z_STRLEN_P(str)) {
    1099           3 :                 zend_long old_len = Z_STRLEN_P(str);
    1100           6 :                 Z_STR_P(str) = zend_string_realloc(Z_STR_P(str), offset + 1, 0);
    1101           3 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    1102           3 :                 memset(Z_STRVAL_P(str) + old_len, ' ', offset - old_len);
    1103           3 :                 Z_STRVAL_P(str)[offset+1] = 0;
    1104         141 :         } else if (!Z_REFCOUNTED_P(str)) {
    1105          16 :                 Z_STR_P(str) = zend_string_init(Z_STRVAL_P(str), Z_STRLEN_P(str), 0);
    1106           8 :                 Z_TYPE_INFO_P(str) = IS_STRING_EX;
    1107             :         }
    1108             : 
    1109         144 :         if (Z_TYPE_P(value) != IS_STRING) {
    1110          11 :                 zend_string *tmp = zval_get_string(value);
    1111             : 
    1112          11 :                 Z_STRVAL_P(str)[offset] = tmp->val[0];
    1113             :                 zend_string_release(tmp);
    1114             :         } else {
    1115         133 :                 Z_STRVAL_P(str)[offset] = Z_STRVAL_P(value)[0];
    1116             :         }
    1117             :         /*
    1118             :          * the value of an assignment to a string offset is undefined
    1119             :         T(result->u.var).var = &T->str_offset.str;
    1120             :         */
    1121             : 
    1122             :         zend_string_release(old_str);
    1123         144 :         if (result) {
    1124          12 :                 zend_uchar c = (zend_uchar)Z_STRVAL_P(str)[offset];
    1125             : 
    1126          12 :                 if (CG(one_char_string)[c]) {
    1127           0 :                         ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1128             :                 } else {
    1129          24 :                         ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(str) + offset, 1, 0));
    1130             :                 }
    1131             :         }
    1132             : }
    1133             : 
    1134             : /* Utility Functions for Extensions */
    1135           0 : static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array)
    1136             : {
    1137           0 :         if (extension->statement_handler) {
    1138           0 :                 extension->statement_handler(op_array);
    1139             :         }
    1140           0 : }
    1141             : 
    1142             : 
    1143           0 : static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array)
    1144             : {
    1145           0 :         if (extension->fcall_begin_handler) {
    1146           0 :                 extension->fcall_begin_handler(op_array);
    1147             :         }
    1148           0 : }
    1149             : 
    1150             : 
    1151           0 : static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array)
    1152             : {
    1153           0 :         if (extension->fcall_end_handler) {
    1154           0 :                 extension->fcall_end_handler(op_array);
    1155             :         }
    1156           0 : }
    1157             : 
    1158             : 
    1159             : static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_data *execute_data, int fetch_type)
    1160             : {
    1161             :         HashTable *ht;
    1162             : 
    1163      214898 :         if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
    1164      107449 :             EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
    1165       13534 :                 ht = &EG(symbol_table);
    1166       93915 :         } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
    1167             :                 ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
    1168        1449 :                 ht = EX(func)->op_array.static_variables;
    1169             :         } else {
    1170             :                 ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL);
    1171       92466 :                 if (!EX(symbol_table)) {
    1172       87388 :                         zend_rebuild_symbol_table();
    1173             :                 }
    1174       92466 :                 ht = EX(symbol_table);
    1175             :         }
    1176      107449 :         return ht;
    1177             : }
    1178             : 
    1179             : static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type)
    1180             : {
    1181             :         zval *retval;
    1182             :         zend_string *offset_key;
    1183             :         zend_ulong hval;
    1184             : 
    1185             : try_again:
    1186     9577182 :         if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
    1187     4738884 :                 hval = Z_LVAL_P(dim);
    1188             : num_index:
    1189     4919037 :                 retval = zend_hash_index_find(ht, hval);
    1190     4919037 :                 if (retval == NULL) {
    1191      396739 :                         switch (type) {
    1192             :                                 case BP_VAR_R:
    1193          16 :                                         zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
    1194             :                                         /* break missing intentionally */
    1195             :                                 case BP_VAR_UNSET:
    1196             :                                 case BP_VAR_IS:
    1197          19 :                                         retval = &EG(uninitialized_zval);
    1198             :                                         break;
    1199             :                                 case BP_VAR_RW:
    1200           6 :                                         zend_error(E_NOTICE,"Undefined offset: " ZEND_ULONG_FMT, hval);
    1201             :                                         /* break missing intentionally */
    1202             :                                 case BP_VAR_W:
    1203      396720 :                                         retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
    1204             :                                         break;
    1205             :                         }
    1206             :                 }
    1207     4838298 :         } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
    1208     3738716 :                 offset_key = Z_STR_P(dim);
    1209     3738716 :                 if (dim_type != IS_CONST) {
    1210     6074332 :                         if (ZEND_HANDLE_NUMERIC(offset_key, hval)) {
    1211             :                                 goto num_index;
    1212             :                         }
    1213             :                 }
    1214             : str_index:
    1215     3558642 :                 retval = zend_hash_find(ht, offset_key);
    1216     3558642 :                 if (retval) {
    1217             :                         /* support for $GLOBALS[...] */
    1218     1605671 :                         if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
    1219        7859 :                                 retval = Z_INDIRECT_P(retval);
    1220        7859 :                                 if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
    1221          21 :                                         switch (type) {
    1222             :                                                 case BP_VAR_R:
    1223           1 :                                                         zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
    1224             :                                                         /* break missing intentionally */
    1225             :                                                 case BP_VAR_UNSET:
    1226             :                                                 case BP_VAR_IS:
    1227           1 :                                                         retval = &EG(uninitialized_zval);
    1228             :                                                         break;
    1229             :                                                 case BP_VAR_RW:
    1230           0 :                                                         zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
    1231             :                                                         /* break missing intentionally */
    1232             :                                                 case BP_VAR_W:
    1233          20 :                                                         ZVAL_NULL(retval);
    1234             :                                                         break;
    1235             :                                         }
    1236             :                                 }
    1237             :                         }
    1238             :                 } else {
    1239     1952971 :                         switch (type) {
    1240             :                                 case BP_VAR_R:
    1241      159615 :                                         zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
    1242             :                                         /* break missing intentionally */
    1243             :                                 case BP_VAR_UNSET:
    1244             :                                 case BP_VAR_IS:
    1245      159615 :                                         retval = &EG(uninitialized_zval);
    1246             :                                         break;
    1247             :                                 case BP_VAR_RW:
    1248           1 :                                         zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
    1249             :                                         /* break missing intentionally */
    1250             :                                 case BP_VAR_W:
    1251     1793356 :                                         retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval));
    1252             :                                         break;
    1253             :                         }
    1254             :                 }
    1255             :         } else {
    1256     1099582 :                 switch (Z_TYPE_P(dim)) {
    1257             :                         case IS_NULL:
    1258          11 :                                 offset_key = STR_EMPTY_ALLOC();
    1259             :                                 goto str_index;
    1260             :                         case IS_DOUBLE:
    1261         112 :                                 hval = zend_dval_to_lval(Z_DVAL_P(dim));
    1262             :                                 goto num_index;
    1263             :                         case IS_RESOURCE:
    1264           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));
    1265           3 :                                 hval = Z_RES_HANDLE_P(dim);
    1266             :                                 goto num_index;
    1267             :                         case IS_FALSE:
    1268           6 :                                 hval = 0;
    1269             :                                 goto num_index;
    1270             :                         case IS_TRUE:
    1271           3 :                                 hval = 1;
    1272             :                                 goto num_index;
    1273             :                         case IS_REFERENCE:
    1274     1099497 :                                 dim = Z_REFVAL_P(dim);
    1275             :                                 goto try_again;
    1276             :                         default:
    1277           6 :                                 zend_error(E_WARNING, "Illegal offset type");
    1278           6 :                                 retval = (type == BP_VAR_W || type == BP_VAR_RW) ?
    1279             :                                         &EG(error_zval) : &EG(uninitialized_zval);
    1280             :                 }
    1281             :         }
    1282     8477685 :         return retval;
    1283             : }
    1284             : 
    1285         152 : static zend_never_inline zend_long zend_check_string_offset(zval *dim, int type)
    1286             : {
    1287             :         zend_long offset;
    1288             : 
    1289         152 :         if (dim == NULL) {
    1290           0 :                 zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
    1291             :         }
    1292             : 
    1293             : try_again:
    1294         152 :         if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1295          15 :                 switch(Z_TYPE_P(dim)) {
    1296             :                         case IS_STRING:
    1297          30 :                                 if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1298           0 :                                         break;
    1299             :                                 }
    1300          15 :                                 if (type != BP_VAR_UNSET) {
    1301          14 :                                         zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1302             :                                 }
    1303          15 :                                 break;
    1304             :                         case IS_DOUBLE:
    1305             :                         case IS_NULL:
    1306             :                         case IS_FALSE:
    1307             :                         case IS_TRUE:
    1308           0 :                                 zend_error(E_NOTICE, "String offset cast occurred");
    1309           0 :                                 break;
    1310             :                         case IS_REFERENCE:
    1311           0 :                                 dim = Z_REFVAL_P(dim);
    1312           0 :                                 goto try_again;
    1313             :                         default:
    1314           0 :                                 zend_error(E_WARNING, "Illegal offset type");
    1315             :                                 break;
    1316             :                 }
    1317             : 
    1318          15 :                 offset = zval_get_long(dim);
    1319             :         } else {
    1320         137 :                 offset = Z_LVAL_P(dim);
    1321             :         }
    1322             : 
    1323         152 :         return offset;
    1324             : }
    1325             : 
    1326             : static zend_always_inline zend_long zend_fetch_string_offset(zval *container, zval *dim, int type)
    1327             : {
    1328         145 :         zend_long offset = zend_check_string_offset(dim, type);
    1329             : 
    1330         145 :         if (Z_REFCOUNTED_P(container)) {
    1331         136 :                 if (Z_REFCOUNT_P(container) > 1) {
    1332             :                         Z_DELREF_P(container);
    1333           6 :                         zval_copy_ctor_func(container);
    1334             :                 }
    1335             :                 Z_ADDREF_P(container);
    1336             :         }
    1337         145 :         return offset;
    1338             : }
    1339             : 
    1340             : static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container, zval *dim, int dim_type, int type)
    1341             : {
    1342             :     zval *retval;
    1343             : 
    1344             : try_again:
    1345     4535278 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1346     9121634 :                 SEPARATE_ARRAY(container);
    1347             : fetch_from_array:
    1348     4511403 :                 if (dim == NULL) {
    1349      564029 :                         retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
    1350      564029 :                         if (UNEXPECTED(retval == NULL)) {
    1351           2 :                                 zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
    1352           2 :                                 retval = &EG(error_zval);
    1353             :                         }
    1354             :                 } else {
    1355     7894748 :                         retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
    1356             :                 }
    1357     4511403 :                 ZVAL_INDIRECT(result, retval);
    1358       25060 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1359          11 :                 if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
    1360             :                         zval_ptr_dtor_nogc(container);
    1361             : convert_to_array:
    1362        1185 :                         ZVAL_NEW_ARR(container);
    1363        1185 :                         zend_hash_init(Z_ARRVAL_P(container), 8, NULL, ZVAL_PTR_DTOR, 0);
    1364             :                         goto fetch_from_array;
    1365             :                 }
    1366             : 
    1367           7 :                 zend_check_string_offset(dim, type);
    1368             : 
    1369           7 :                 ZVAL_INDIRECT(result, NULL); /* wrong string offset */
    1370       25049 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1371          52 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1372           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1373             :                 } else {
    1374          52 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result);
    1375             : 
    1376          52 :                         if (UNEXPECTED(retval == &EG(uninitialized_zval))) {
    1377           2 :                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1378             : 
    1379           2 :                                 ZVAL_NULL(result);
    1380           2 :                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
    1381          96 :                         } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) {
    1382          46 :                                 if (!Z_ISREF_P(retval)) {
    1383          76 :                                         if (Z_REFCOUNTED_P(retval) &&
    1384             :                                             Z_REFCOUNT_P(retval) > 1) {
    1385           7 :                                                 if (Z_TYPE_P(retval) != IS_OBJECT) {
    1386             :                                                         Z_DELREF_P(retval);
    1387           5 :                                                         ZVAL_DUP(result, retval);
    1388           5 :                                                         retval = result;
    1389             :                                                 } else {
    1390           2 :                                                         ZVAL_COPY(result, retval);
    1391           2 :                                                         retval = result;
    1392             :                                                 }
    1393             :                                         }
    1394          40 :                                         if (Z_TYPE_P(retval) != IS_OBJECT) {
    1395           9 :                                                 zend_class_entry *ce = Z_OBJCE_P(container);
    1396           9 :                                                 zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
    1397             :                                         }
    1398             :                                 }
    1399          46 :                                 if (result != retval) {
    1400           5 :                                         ZVAL_INDIRECT(result, retval);
    1401             :                                 }
    1402             :                         } else {
    1403           4 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1404             :                         }
    1405             :                 }
    1406       24997 :         } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
    1407        1183 :                 if (UNEXPECTED(container == &EG(error_zval))) {
    1408           2 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1409        1181 :                 } else if (type != BP_VAR_UNSET) {
    1410             :                         goto convert_to_array;
    1411             :                 } else {
    1412             :                         /* for read-mode only */
    1413           0 :                         ZVAL_NULL(result);
    1414             :                 }
    1415       23814 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
    1416       23795 :                 container = Z_REFVAL_P(container);
    1417             :                 goto try_again;
    1418             :         } else {
    1419          19 :                 if (type == BP_VAR_UNSET) {
    1420           0 :                         zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
    1421           0 :                         ZVAL_NULL(result);
    1422             :                 } else {
    1423          19 :                         zend_error(E_WARNING, "Cannot use a scalar value as an array");
    1424          19 :                         ZVAL_INDIRECT(result, &EG(error_zval));
    1425             :                 }
    1426             :         }
    1427             : }
    1428             : 
    1429     3241785 : static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1430             : {
    1431             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W);
    1432     3241785 : }
    1433             : 
    1434     1269680 : static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1435             : {
    1436             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW);
    1437     1269680 : }
    1438             : 
    1439          18 : static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type)
    1440             : {
    1441             :         zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET);
    1442          18 : }
    1443             : 
    1444             : static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type)
    1445             : {
    1446             :         zval *retval;
    1447             : 
    1448             : try_again:
    1449     5455017 :         if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
    1450     8646494 :                 retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type);
    1451     4323247 :                 ZVAL_COPY(result, retval);
    1452     1131770 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
    1453             :                 zend_long offset;
    1454             : 
    1455             : try_string_offset:
    1456       32130 :                 if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
    1457          46 :                         switch(Z_TYPE_P(dim)) {
    1458             :                                 /* case IS_LONG: */
    1459             :                                 case IS_STRING:
    1460          60 :                                         if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
    1461             :                                                 break;
    1462             :                                         }
    1463          29 :                                         if (type != BP_VAR_IS) {
    1464          21 :                                                 zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
    1465             :                                         }
    1466             :                                         break;
    1467             :                                 case IS_DOUBLE:
    1468             :                                 case IS_NULL:
    1469             :                                 case IS_FALSE:
    1470             :                                 case IS_TRUE:
    1471          13 :                                         if (type != BP_VAR_IS) {
    1472          11 :                                                 zend_error(E_NOTICE, "String offset cast occurred");
    1473             :                                         }
    1474             :                                         break;
    1475             :                                 case IS_REFERENCE:
    1476           0 :                                         dim = Z_REFVAL_P(dim);
    1477             :                                         goto try_string_offset;
    1478             :                                 default:
    1479           3 :                                         zend_error(E_WARNING, "Illegal offset type");
    1480             :                                         break;
    1481             :                         }
    1482             : 
    1483          46 :                         offset = zval_get_long(dim);
    1484             :                 } else {
    1485       32084 :                         offset = Z_LVAL_P(dim);
    1486             :                 }
    1487             : 
    1488       32130 :                 if (UNEXPECTED(offset < 0) || UNEXPECTED(Z_STRLEN_P(container) <= (size_t)offset)) {
    1489          37 :                         if (type != BP_VAR_IS) {
    1490          33 :                                 zend_error(E_NOTICE, "Uninitialized string offset: %pd", offset);
    1491             :                         }
    1492          37 :                         ZVAL_EMPTY_STRING(result);
    1493             :                 } else {
    1494       32093 :                         zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[offset];
    1495             : 
    1496       32093 :                         if (CG(one_char_string)[c]) {
    1497           0 :                                 ZVAL_INTERNED_STR(result, CG(one_char_string)[c]);
    1498             :                         } else {
    1499       64186 :                                 ZVAL_NEW_STR(result, zend_string_init(Z_STRVAL_P(container) + offset, 1, 0));
    1500             :                         }
    1501             :                 }
    1502     1099640 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1503         761 :                 if (!Z_OBJ_HT_P(container)->read_dimension) {
    1504           0 :                         zend_error_noreturn(E_ERROR, "Cannot use object as array");
    1505             :                 } else {
    1506         761 :                         retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result);
    1507             : 
    1508             :                         ZEND_ASSERT(result != NULL);
    1509         758 :                         if (retval) {
    1510         750 :                                 if (result != retval) {
    1511         122 :                                         ZVAL_COPY(result, retval);
    1512             :                                 }
    1513             :                         } else {
    1514           8 :                                 ZVAL_NULL(result);
    1515             :                         }
    1516             :                 }
    1517     1098879 :         } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
    1518     1098754 :                 container = Z_REFVAL_P(container);
    1519             :                 goto try_again;
    1520             :         } else {
    1521         125 :                 ZVAL_NULL(result);
    1522             :         }
    1523             : }
    1524             : 
    1525     4355383 : static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type)
    1526             : {
    1527             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R);
    1528     4355380 : }
    1529             : 
    1530         880 : static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type)
    1531             : {
    1532             :         zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS);
    1533         880 : }
    1534             : 
    1535          11 : ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim)
    1536             : {
    1537          11 :         zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR);
    1538          11 : }
    1539             : 
    1540             : 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)
    1541             : {
    1542      263532 :     if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
    1543             :                 do {
    1544          85 :                         if (container_op_type != IS_VAR && UNEXPECTED(container == &EG(error_zval))) {
    1545           0 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1546             :                                 return;
    1547             :                         }
    1548             : 
    1549          85 :                         if (Z_ISREF_P(container)) {
    1550          41 :                                 container = Z_REFVAL_P(container);
    1551          41 :                                 if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
    1552             :                                         break;
    1553             :                                 }
    1554             :                         }
    1555             : 
    1556             :                         /* this should modify object only if it's empty */
    1557          97 :                         if (type != BP_VAR_UNSET &&
    1558           3 :                             EXPECTED(Z_TYPE_P(container) <= IS_FALSE ||
    1559             :                               (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0))) {
    1560             :                                 zval_ptr_dtor_nogc(container);
    1561          38 :                                 object_init(container);
    1562             :                         } else {
    1563           6 :                                 zend_error(E_WARNING, "Attempt to modify property of non-object");
    1564           6 :                                 ZVAL_INDIRECT(result, &EG(error_zval));
    1565             :                                 return;
    1566             :                         }
    1567             :                 } while (0);
    1568             :         }
    1569      351328 :         if (prop_op_type == IS_CONST &&
    1570      175655 :             EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) {
    1571      175200 :                 uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
    1572      175200 :                 zend_object *zobj = Z_OBJ_P(container);
    1573             :                 zval *retval;
    1574             : 
    1575      175200 :                 if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) {
    1576      174993 :                         retval = OBJ_PROP(zobj, prop_offset);
    1577      174993 :                         if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) {
    1578      174993 :                                 ZVAL_INDIRECT(result, retval);
    1579             :                                 return;
    1580             :                         }
    1581         207 :                 } else if (EXPECTED(zobj->properties != NULL)) {
    1582         201 :                         retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr));
    1583         201 :                         if (EXPECTED(retval)) {
    1584           2 :                                 ZVAL_INDIRECT(result, retval);
    1585             :                                 return;
    1586             :                         }
    1587             :                 }
    1588             :         }
    1589         678 :         if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) {
    1590         678 :                 zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot);
    1591         677 :                 if (NULL == ptr) {
    1592         110 :                         if (Z_OBJ_HT_P(container)->read_property &&
    1593          55 :                                 (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result)) != NULL) {
    1594          55 :                                 if (ptr != result) {
    1595           2 :                                         ZVAL_INDIRECT(result, ptr);
    1596             :                                 }
    1597             :                         } else {
    1598           0 :                                 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
    1599             :                         }
    1600             :                 } else {
    1601         622 :                         ZVAL_INDIRECT(result, ptr);
    1602             :                 }
    1603           0 :         } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
    1604           0 :                 zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result);
    1605           0 :                 if (ptr != result) {
    1606           0 :                         ZVAL_INDIRECT(result, ptr);
    1607             :                 }
    1608             :         } else {
    1609           0 :                 zend_error(E_WARNING, "This object doesn't support property references");
    1610           0 :                 ZVAL_INDIRECT(result, &EG(error_zval));
    1611             :         }
    1612             : }
    1613             : 
    1614       78627 : 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)
    1615             : {
    1616       78627 :         int original_nest_levels = nest_levels;
    1617             :         zend_brk_cont_element *jmp_to;
    1618             : 
    1619             :         do {
    1620       78789 :                 if (array_offset==-1) {
    1621           1 :                         zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
    1622             :                 }
    1623       78788 :                 jmp_to = &op_array->brk_cont_array[array_offset];
    1624       78788 :                 if (nest_levels>1) {
    1625         162 :                         zend_op *brk_opline = &op_array->opcodes[jmp_to->brk];
    1626             : 
    1627         162 :                         if (brk_opline->opcode == ZEND_FREE) {
    1628           1 :                                 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
    1629           1 :                                         zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
    1630             :                                 }
    1631         161 :                         } else if (brk_opline->opcode == ZEND_FE_FREE) {
    1632           6 :                                 if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
    1633           4 :                                         zval *var = EX_VAR(brk_opline->op1.var);
    1634           4 :                                         if (Z_TYPE_P(var) != IS_ARRAY && Z_FE_ITER_P(var) != (uint32_t)-1) {
    1635           0 :                                                 zend_hash_iterator_del(Z_FE_ITER_P(var));
    1636             :                                         }
    1637             :                                         zval_ptr_dtor_nogc(var);
    1638             :                                 }
    1639             :                         }
    1640             :                 }
    1641       78788 :                 array_offset = jmp_to->parent;
    1642       78788 :         } while (--nest_levels > 0);
    1643       78626 :         return jmp_to;
    1644             : }
    1645             : 
    1646             : #if ZEND_INTENSIVE_DEBUGGING
    1647             : 
    1648             : #define CHECK_SYMBOL_TABLES()                                                                                                   \
    1649             :         zend_hash_apply(&EG(symbol_table), zend_check_symbol);                      \
    1650             :         if (&EG(symbol_table)!=EX(symbol_table)) {                                                  \
    1651             :                 zend_hash_apply(EX(symbol_table), zend_check_symbol);   \
    1652             :         }
    1653             : 
    1654             : static int zend_check_symbol(zval *pz)
    1655             : {
    1656             :         if (Z_TYPE_P(pz) == IS_INDIRECT) {
    1657             :                 pz = Z_INDIRECT_P(pz);
    1658             :         }
    1659             :         if (Z_TYPE_P(pz) > 10) {
    1660             :                 fprintf(stderr, "Warning!  %x has invalid type!\n", *pz);
    1661             : /* See http://support.microsoft.com/kb/190351 */
    1662             : #ifdef PHP_WIN32
    1663             :                 fflush(stderr);
    1664             : #endif
    1665             :         } else if (Z_TYPE_P(pz) == IS_ARRAY) {
    1666             :                 zend_hash_apply(Z_ARRVAL_P(pz), zend_check_symbol);
    1667             :         } else if (Z_TYPE_P(pz) == IS_OBJECT) {
    1668             :                 /* OBJ-TBI - doesn't support new object model! */
    1669             :                 zend_hash_apply(Z_OBJPROP_P(pz), zend_check_symbol);
    1670             :         }
    1671             : 
    1672             :         return 0;
    1673             : }
    1674             : 
    1675             : 
    1676             : #else
    1677             : #define CHECK_SYMBOL_TABLES()
    1678             : #endif
    1679             : 
    1680             : ZEND_API opcode_handler_t *zend_opcode_handlers;
    1681             : 
    1682           0 : ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value)
    1683             : {
    1684           0 :         execute_data->func->internal_function.handler(execute_data, return_value);
    1685           0 : }
    1686             : 
    1687       87833 : ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
    1688             : {
    1689       87833 :         if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
    1690           0 :                 zend_array_destroy(symbol_table);
    1691           0 :                 efree_size(symbol_table, sizeof(zend_array));
    1692             :         } else {
    1693             :                 /* clean before putting into the cache, since clean
    1694             :                    could call dtors, which could use cached hash */
    1695       87833 :                 zend_symtable_clean(symbol_table);
    1696       87833 :                 *(++EG(symtable_cache_ptr)) = symbol_table;
    1697             :         }
    1698       87833 : }
    1699             : /* }}} */
    1700             : 
    1701             : static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
    1702             : {
    1703     1711659 :         if (EXPECTED(EX(func)->op_array.last_var > 0)) {
    1704     1506841 :                 zval *cv = EX_VAR_NUM(0);
    1705     1506841 :                 zval *end = cv + EX(func)->op_array.last_var;
    1706             :                 do {
    1707             :                         zval_ptr_dtor(cv);
    1708     7995616 :                         cv++;
    1709     7995616 :                 } while (cv != end);
    1710             :         }
    1711             : }
    1712             : /* }}} */
    1713             : 
    1714          89 : void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
    1715             : {
    1716             :         i_free_compiled_variables(execute_data);
    1717          89 : }
    1718             : /* }}} */
    1719             : 
    1720             : /*
    1721             :  * Stack Frame Layout (the whole stack frame is allocated at once)
    1722             :  * ==================
    1723             :  *
    1724             :  *                             +========================================+
    1725             :  * EG(current_execute_data) -> | zend_execute_data                      |
    1726             :  *                             +----------------------------------------+
    1727             :  *     EX_CV_NUM(0) ---------> | VAR[0] = ARG[1]                        |
    1728             :  *                             | ...                                    |
    1729             :  *                             | VAR[op_array->num_args-1] = ARG[N]     |
    1730             :  *                             | ...                                    |
    1731             :  *                             | VAR[op_array->last_var-1]              |
    1732             :  *                             | VAR[op_array->last_var] = TMP[0]       |
    1733             :  *                             | ...                                    |
    1734             :  *                             | VAR[op_array->last_var+op_array->T-1]  |
    1735             :  *                             | ARG[N+1] (extra_args)                  |
    1736             :  *                             | ...                                    |
    1737             :  *                             +----------------------------------------+
    1738             :  */
    1739             : 
    1740             : static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1741             : {
    1742             :         uint32_t first_extra_arg, num_args;
    1743             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1744             : 
    1745     1269945 :         EX(opline) = op_array->opcodes;
    1746     1269945 :         EX(call) = NULL;
    1747     1269945 :         EX(return_value) = return_value;
    1748             : 
    1749             :         /* Handle arguments */
    1750     1269945 :         first_extra_arg = op_array->num_args;
    1751     1269945 :         num_args = EX_NUM_ARGS();
    1752     1269945 :         if (UNEXPECTED(num_args > first_extra_arg)) {
    1753             :                 zval *end, *src, *dst;
    1754          98 :                 uint32_t type_flags = 0;
    1755             : 
    1756          98 :                 if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1757             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1758          95 :                         EX(opline) += first_extra_arg;
    1759             :                 }
    1760             : 
    1761             :                 /* move extra args into separate array after all CV and TMP vars */
    1762          98 :                 end = EX_VAR_NUM(first_extra_arg - 1);
    1763          98 :                 src = end + (num_args - first_extra_arg);
    1764          98 :                 dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    1765          98 :                 if (EXPECTED(src != dst)) {
    1766             :                         do {
    1767       20174 :                                 type_flags |= Z_TYPE_INFO_P(src);
    1768       20174 :                                 ZVAL_COPY_VALUE(dst, src);
    1769       20174 :                                 ZVAL_UNDEF(src);
    1770       20174 :                                 src--;
    1771       20174 :                                 dst--;
    1772       20174 :                         } while (src != end);
    1773             :                 } else {
    1774             :                         do {
    1775         326 :                                 type_flags |= Z_TYPE_INFO_P(src);
    1776         326 :                                 src--;
    1777         326 :                         } while (src != end);
    1778             :                 }
    1779          98 :                 ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
    1780     1269847 :         } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1781             :                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1782     1181828 :                 EX(opline) += num_args;
    1783             :         }
    1784             : 
    1785             :         /* Initialize CV variables (skip arguments) */
    1786     1269945 :         if (EXPECTED((int)num_args < op_array->last_var)) {
    1787      697322 :                 zval *var = EX_VAR_NUM(num_args);
    1788      697322 :                 zval *end = EX_VAR_NUM(op_array->last_var);
    1789             : 
    1790             :                 do {
    1791     3833013 :                         ZVAL_UNDEF(var);
    1792     3833013 :                         var++;
    1793     3833013 :                 } while (var != end);
    1794             :         }
    1795             : 
    1796     1269945 :         if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
    1797       97806 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
    1798       97806 :                 GC_REFCOUNT(Z_OBJ(EX(This)))++;
    1799             :         }
    1800             : 
    1801     1269945 :         if (UNEXPECTED(!op_array->run_time_cache)) {
    1802       16156 :                 op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
    1803             :         }
    1804     1269945 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    1805     1269945 :         EX_LOAD_LITERALS(op_array);
    1806             : 
    1807     1269945 :         EG(current_execute_data) = execute_data;
    1808             : }
    1809             : /* }}} */
    1810             : 
    1811             : static zend_always_inline void i_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1812             : {
    1813             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1814             : 
    1815        9172 :         EX(opline) = op_array->opcodes;
    1816        9172 :         EX(call) = NULL;
    1817        9172 :         EX(return_value) = return_value;
    1818             : 
    1819        9172 :         zend_attach_symbol_table(execute_data);
    1820             : 
    1821        9172 :         if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
    1822           1 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
    1823           1 :                 GC_REFCOUNT(Z_OBJ(EX(This)))++;
    1824             :         }
    1825             : 
    1826        9172 :         if (!op_array->run_time_cache) {
    1827        9172 :                 op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
    1828             :         }
    1829        9172 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    1830        9172 :         EX_LOAD_LITERALS(op_array);
    1831             : 
    1832        9172 :         EG(current_execute_data) = execute_data;
    1833             : }
    1834             : /* }}} */
    1835             : 
    1836             : static zend_always_inline void i_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1837             : {
    1838             :         ZEND_ASSERT(EX(func) == (zend_function*)op_array);
    1839             : 
    1840      462592 :         EX(opline) = op_array->opcodes;
    1841      462592 :         EX(call) = NULL;
    1842      462592 :         EX(return_value) = return_value;
    1843             : 
    1844      462592 :         if (UNEXPECTED(EX(symbol_table) != NULL)) {
    1845       20713 :                 zend_attach_symbol_table(execute_data);
    1846             :         } else {
    1847             :                 uint32_t first_extra_arg, num_args;
    1848             : 
    1849             :                 /* Handle arguments */
    1850      441879 :                 first_extra_arg = op_array->num_args;
    1851      441879 :                 num_args = EX_NUM_ARGS();
    1852      441879 :                 if (UNEXPECTED(num_args > first_extra_arg)) {
    1853             :                         zval *end, *src, *dst;
    1854        1003 :                         uint32_t type_flags = 0;
    1855             : 
    1856        1003 :                         if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1857             :                                 /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1858        1001 :                                 EX(opline) += first_extra_arg;
    1859             :                         }
    1860             : 
    1861             :                         /* move extra args into separate array after all CV and TMP vars */
    1862        1003 :                         end = EX_VAR_NUM(first_extra_arg - 1);
    1863        1003 :                         src = end + (num_args - first_extra_arg);
    1864        1003 :                         dst = src + (op_array->last_var + op_array->T - first_extra_arg);
    1865        1003 :                         if (EXPECTED(src != dst)) {
    1866             :                                 do {
    1867        1324 :                                         type_flags |= Z_TYPE_INFO_P(src);
    1868        1324 :                                         ZVAL_COPY_VALUE(dst, src);
    1869        1324 :                                         ZVAL_UNDEF(src);
    1870        1324 :                                         src--;
    1871        1324 :                                         dst--;
    1872        1324 :                                 } while (src != end);
    1873             :                         } else {
    1874             :                                 do {
    1875        1335 :                                         type_flags |= Z_TYPE_INFO_P(src);
    1876        1335 :                                         src--;
    1877        1335 :                                 } while (src != end);
    1878             :                         }
    1879        1003 :                         ZEND_ADD_CALL_FLAG(execute_data, ((type_flags >> Z_TYPE_FLAGS_SHIFT) & IS_TYPE_REFCOUNTED));
    1880      440876 :                 } else if (EXPECTED((op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) == 0)) {
    1881             :                         /* Skip useless ZEND_RECV and ZEND_RECV_INIT opcodes */
    1882      440859 :                         EX(opline) += num_args;
    1883             :                 }
    1884             : 
    1885             :                 /* Initialize CV variables (skip arguments) */
    1886      441879 :                 if (EXPECTED((int)num_args < op_array->last_var)) {
    1887      203481 :                         zval *var = EX_VAR_NUM(num_args);
    1888      203481 :                         zval *end = EX_VAR_NUM(op_array->last_var);
    1889             : 
    1890             :                         do {
    1891      583966 :                                 ZVAL_UNDEF(var);
    1892      583966 :                                 var++;
    1893      583966 :                         } while (var != end);
    1894             :                 }
    1895             :         }
    1896             : 
    1897      462592 :         if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) {
    1898       17466 :                 ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This)));
    1899       17466 :                 GC_REFCOUNT(Z_OBJ(EX(This)))++;
    1900             :         }
    1901             : 
    1902      462592 :         if (!op_array->run_time_cache) {
    1903       23785 :                 if (op_array->function_name) {
    1904        6144 :                         op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
    1905             :                 } else {
    1906       20713 :                         op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
    1907             :                 }
    1908             :         }
    1909      462592 :         EX_LOAD_RUN_TIME_CACHE(op_array);
    1910      462592 :         EX_LOAD_LITERALS(op_array);
    1911             : 
    1912      462592 :         EG(current_execute_data) = execute_data;
    1913             : }
    1914             : /* }}} */
    1915             : 
    1916          89 : ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data *call, zend_op_array *op_array, zval *return_value) /* {{{ */
    1917             : {
    1918             :         /*
    1919             :          * Normally the execute_data is allocated on the VM stack (because it does
    1920             :          * not actually do any allocation and thus is faster). For generators
    1921             :          * though this behavior would be suboptimal, because the (rather large)
    1922             :          * structure would have to be copied back and forth every time execution is
    1923             :          * suspended or resumed. That's why for generators the execution context
    1924             :          * is allocated using a separate VM stack, thus allowing to save and
    1925             :          * restore it simply by replacing a pointer.
    1926             :          */
    1927             :         zend_execute_data *execute_data;
    1928          89 :         uint32_t num_args = ZEND_CALL_NUM_ARGS(call);
    1929          89 :         size_t stack_size = (ZEND_CALL_FRAME_SLOT + MAX(op_array->last_var + op_array->T, num_args)) * sizeof(zval);
    1930             : 
    1931         178 :         EG(vm_stack) = zend_vm_stack_new_page(
    1932          89 :                 EXPECTED(stack_size < ZEND_VM_STACK_FREE_PAGE_SIZE) ?
    1933             :                         ZEND_VM_STACK_PAGE_SIZE :
    1934           0 :                         ZEND_VM_STACK_PAGE_ALIGNED_SIZE(stack_size),
    1935             :                 NULL);
    1936          89 :         EG(vm_stack_top) = EG(vm_stack)->top;
    1937          89 :         EG(vm_stack_end) = EG(vm_stack)->end;
    1938             : 
    1939         178 :         execute_data = zend_vm_stack_push_call_frame(
    1940             :                 ZEND_CALL_TOP_FUNCTION,
    1941             :                 (zend_function*)op_array,
    1942             :                 num_args,
    1943             :                 call->called_scope,
    1944             :                 Z_OBJ(call->This),
    1945             :                 NULL);
    1946          89 :         EX_NUM_ARGS() = num_args;
    1947             : 
    1948             :         /* copy arguments */
    1949          89 :         if (num_args > 0) {
    1950          25 :                 zval *arg_src = ZEND_CALL_ARG(call, 1);
    1951          25 :                 zval *arg_dst = ZEND_CALL_ARG(execute_data, 1);
    1952             :                 uint32_t i;
    1953             : 
    1954          59 :                 for (i = 0; i < num_args; i++) {
    1955          34 :                         ZVAL_COPY_VALUE(arg_dst + i, arg_src + i);
    1956             :                 }
    1957             :         }
    1958             : 
    1959          89 :         EX(symbol_table) = NULL;
    1960             : 
    1961             :         i_init_func_execute_data(execute_data, op_array, return_value);
    1962             : 
    1963          89 :         return execute_data;
    1964             : }
    1965             : /* }}} */
    1966             : 
    1967      441879 : ZEND_API void zend_init_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
    1968             : {
    1969      441879 :         EX(prev_execute_data) = EG(current_execute_data);
    1970             :         i_init_execute_data(execute_data, op_array, return_value);
    1971      441879 : }
    1972             : /* }}} */
    1973             : 
    1974             : static zend_always_inline zend_bool zend_is_by_ref_func_arg_fetch(const zend_op *opline, zend_execute_data *call) /* {{{ */
    1975             : {
    1976        3457 :         uint32_t arg_num = opline->extended_value & ZEND_FETCH_ARG_MASK;
    1977        6914 :         return ARG_SHOULD_BE_SENT_BY_REF(call->func, arg_num);
    1978             : }
    1979             : /* }}} */
    1980             : 
    1981           3 : static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
    1982             : {
    1983             :         zend_execute_data *new_call;
    1984           3 :         int used_stack = (EG(vm_stack_top) - (zval*)call) + additional_args;
    1985             : 
    1986             :         /* copy call frame into new stack segment */
    1987           3 :         new_call = zend_vm_stack_extend(used_stack * sizeof(zval));
    1988           3 :         *new_call = *call;
    1989           3 :         if (passed_args) {
    1990           1 :                 zval *src = ZEND_CALL_ARG(call, 1);
    1991           1 :                 zval *dst = ZEND_CALL_ARG(new_call, 1);
    1992             :                 do {
    1993       10000 :                         ZVAL_COPY_VALUE(dst, src);
    1994       10000 :                         passed_args--;
    1995       10000 :                         src++;
    1996       10000 :                         dst++;
    1997       10000 :                 } while (passed_args);
    1998             :         }
    1999             : 
    2000             :         /* delete old call_frame from previous stack segment */
    2001           3 :         EG(vm_stack)->prev->top = (zval*)call;
    2002             : 
    2003             :         /* delete previous stack segment if it becames empty */
    2004           3 :         if (UNEXPECTED(EG(vm_stack)->prev->top == ZEND_VM_STACK_ELEMETS(EG(vm_stack)->prev))) {
    2005           0 :                 zend_vm_stack r = EG(vm_stack)->prev;
    2006             : 
    2007           0 :                 EG(vm_stack)->prev = r->prev;
    2008           0 :                 efree(r);
    2009             :         }
    2010             : 
    2011           3 :         return new_call;
    2012             : }
    2013             : /* }}} */
    2014             : 
    2015             : static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data **call, uint32_t passed_args, uint32_t additional_args) /* {{{ */
    2016             : {
    2017         204 :         if (EXPECTED(EG(vm_stack_end) - EG(vm_stack_top) > additional_args)) {
    2018         201 :                 EG(vm_stack_top) += additional_args;
    2019             :         } else {
    2020           3 :                 *call = zend_vm_stack_copy_call_frame(*call, passed_args, additional_args);
    2021             :         }
    2022             : }
    2023             : /* }}} */
    2024             : 
    2025             : #define ZEND_VM_NEXT_OPCODE() \
    2026             :         CHECK_SYMBOL_TABLES() \
    2027             :         ZEND_VM_INC_OPCODE(); \
    2028             :         ZEND_VM_CONTINUE()
    2029             : 
    2030             : #define ZEND_VM_SET_OPCODE(new_op) \
    2031             :         CHECK_SYMBOL_TABLES() \
    2032             :         OPLINE = new_op
    2033             : 
    2034             : #define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
    2035             :         ZEND_VM_SET_OPCODE(ZEND_OFFSET_TO_OPLINE(opline, offset))
    2036             : 
    2037             : #define ZEND_VM_JMP(new_op) \
    2038             :         if (EXPECTED(!EG(exception))) { \
    2039             :                 ZEND_VM_SET_OPCODE(new_op); \
    2040             :         } else { \
    2041             :                 LOAD_OPLINE(); \
    2042             :         } \
    2043             :         ZEND_VM_CONTINUE()
    2044             : 
    2045             : #define ZEND_VM_INC_OPCODE() \
    2046             :         OPLINE++
    2047             : 
    2048             : #ifdef __GNUC__
    2049             : # define ZEND_VM_GUARD(name) __asm__("#" #name)
    2050             : #else
    2051             : # define ZEND_VM_GUARD(name)
    2052             : #endif
    2053             : 
    2054             : #include "zend_vm_execute.h"
    2055             : 
    2056           0 : ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
    2057             : {
    2058           0 :         if (opcode != ZEND_USER_OPCODE) {
    2059           0 :                 if (handler == NULL) {
    2060             :                         /* restore the original handler */
    2061           0 :                         zend_user_opcodes[opcode] = opcode;
    2062             :                 } else {
    2063           0 :                         zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
    2064             :                 }
    2065           0 :                 zend_user_opcode_handlers[opcode] = handler;
    2066           0 :                 return SUCCESS;
    2067             :         }
    2068           0 :         return FAILURE;
    2069             : }
    2070             : 
    2071           0 : ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
    2072             : {
    2073           0 :         return zend_user_opcode_handlers[opcode];
    2074             : }
    2075             : 
    2076           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) {
    2077           0 :         return get_zval_ptr(op_type, *node, execute_data, should_free, type);
    2078             : }
    2079             : 
    2080             : /*
    2081             :  * Local variables:
    2082             :  * tab-width: 4
    2083             :  * c-basic-offset: 4
    2084             :  * indent-tabs-mode: t
    2085             :  * End:
    2086             :  */

Generated by: LCOV version 1.10

Generated at Sun, 01 Mar 2015 23:22:21 +0000 (2 days ago)

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