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: 675 774 87.2 %
Date: 2014-12-13 Functions: 30 38 78.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:09 +0000 (9 days ago)

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