Diff for /embedaddon/php/Zend/zend_execute.c between versions 1.1.1.1 and 1.1.1.4

version 1.1.1.1, 2012/02/21 23:47:52 version 1.1.1.4, 2014/06/15 20:04:03
Line 2 Line 2
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | Zend Engine                                                          |     | Zend Engine                                                          |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
   | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |   | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
    +----------------------------------------------------------------------+     +----------------------------------------------------------------------+
    | This source file is subject to version 2.00 of the Zend license,     |     | This source file is subject to version 2.00 of the Zend license,     |
    | that is bundled with this package in the file LICENSE, and is        |     | that is bundled with this package in the file LICENSE, and is        |
Line 36 Line 36
 #include "zend_interfaces.h"  #include "zend_interfaces.h"
 #include "zend_closures.h"  #include "zend_closures.h"
 #include "zend_vm.h"  #include "zend_vm.h"
   #include "zend_dtrace.h"
   
 /* Virtual current working directory support */  /* Virtual current working directory support */
 #include "tsrm_virtual_cwd.h"  #include "tsrm_virtual_cwd.h"
Line 48 Line 49
   
 typedef int (*incdec_t)(zval *);  typedef int (*incdec_t)(zval *);
   
#define get_zval_ptr(node, Ts, should_free, type) _get_zval_ptr(node, Ts, should_free, type TSRMLS_CC)#define get_zval_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
#define get_zval_ptr_ptr(node, Ts, should_free, type) _get_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC)#define get_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
#define get_obj_zval_ptr(node, Ts, should_free, type) _get_obj_zval_ptr(node, Ts, should_free, type TSRMLS_CC)#define get_obj_zval_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
#define get_obj_zval_ptr_ptr(node, Ts, should_free, type) _get_obj_zval_ptr_ptr(node, Ts, should_free, type TSRMLS_CC)#define get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
   
 /* Prototypes */  /* Prototypes */
 static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);  static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
 static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);  static void zend_extension_fcall_begin_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
 static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);  static void zend_extension_fcall_end_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
   
#define RETURN_VALUE_USED(opline) (!((opline)->result.u.EA.type & EXT_TYPE_UNUSED))#define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
   
 #define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))  
 #define T(offset) (*(temp_variable *)((char *) Ts + offset))  #define T(offset) (*(temp_variable *)((char *) Ts + offset))
   #define CV(var)   CVs[var]
   
 #define TEMP_VAR_STACK_LIMIT 2000  #define TEMP_VAR_STACK_LIMIT 2000
   
Line 92  static zend_always_inline void zend_pzval_unlock_free_ Line 93  static zend_always_inline void zend_pzval_unlock_free_
         }          }
 }  }
   
   #undef zval_ptr_dtor
   #define zval_ptr_dtor(pzv) i_zval_ptr_dtor(*(pzv)  ZEND_FILE_LINE_CC)
   
 #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC)  #define PZVAL_UNLOCK(z, f) zend_pzval_unlock_func(z, f, 1 TSRMLS_CC)
 #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)  #define PZVAL_UNLOCK_EX(z, f, u) zend_pzval_unlock_func(z, f, u TSRMLS_CC)
 #define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC)  #define PZVAL_UNLOCK_FREE(z) zend_pzval_unlock_free_func(z TSRMLS_CC)
 #define PZVAL_LOCK(z) Z_ADDREF_P((z))  #define PZVAL_LOCK(z) Z_ADDREF_P((z))
#define RETURN_VALUE_UNUSED(pzn)        (((pzn)->u.EA.type & EXT_TYPE_UNUSED))#define SELECTIVE_PZVAL_LOCK(pzv, opline)       if (RETURN_VALUE_USED(opline)) { PZVAL_LOCK(pzv); }
#define SELECTIVE_PZVAL_LOCK(pzv, pzn)       if (!RETURN_VALUE_UNUSED(pzn)) { PZVAL_LOCK(pzv); } 
   
#define AI_USE_PTR(ai) \#define EXTRACT_ZVAL_PTR(t) do {                                         \
        if ((ai).ptr_ptr) { \                temp_variable *__t = (t);                                        \
                (ai).ptr = *((ai).ptr_ptr); \                if (__t->var.ptr_ptr) {                                             \
                (ai).ptr_ptr = &((ai).ptr); \                        __t->var.ptr = *__t->var.ptr_ptr;               \
        } else { \                        __t->var.ptr_ptr = &__t->var.ptr;           \
                (ai).ptr = NULL; \                        if (!PZVAL_IS_REF(__t->var.ptr) &&              \
        }                            Z_REFCOUNT_P(__t->var.ptr) > 2) {   \
                                 SEPARATE_ZVAL(__t->var.ptr_ptr);   \
                         }                                                                               \
                 }                                                                                       \
         } while (0)
   
#define AI_SET_PTR(ai, val)          \#define AI_SET_PTR(t, val) do {                            \
        (ai).ptr = (val);                   \                temp_variable *__t = (t);                       \
        (ai).ptr_ptr = &((ai).ptr);                __t->var.ptr = (val);                           \
                 __t->var.ptr_ptr = &__t->var.ptr;       \
         } while (0)
   
 #define FREE_OP(should_free) \  #define FREE_OP(should_free) \
         if (should_free.var) { \          if (should_free.var) { \
Line 134  static zend_always_inline void zend_pzval_unlock_free_ Line 143  static zend_always_inline void zend_pzval_unlock_free_
   
 #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)  #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L)
   
 #define INIT_PZVAL_COPY(z,v) \  
         (z)->value = (v)->value; \  
         Z_TYPE_P(z) = Z_TYPE_P(v); \  
         Z_SET_REFCOUNT_P(z, 1); \  
         Z_UNSET_ISREF_P(z);  
   
 #define MAKE_REAL_ZVAL_PTR(val) \  #define MAKE_REAL_ZVAL_PTR(val) \
         do { \          do { \
                 zval *_tmp; \                  zval *_tmp; \
                 ALLOC_ZVAL(_tmp); \                  ALLOC_ZVAL(_tmp); \
                _tmp->value = (val)->value; \                INIT_PZVAL_COPY(_tmp, (val)); \
                Z_TYPE_P(_tmp) = Z_TYPE_P(val); \                (val) = _tmp; \
                Z_SET_REFCOUNT_P(_tmp, 1); \ 
                Z_UNSET_ISREF_P(_tmp); \ 
                val = _tmp; \ 
         } while (0)          } while (0)
   
 /* End of zend_execute_locks.h */  /* End of zend_execute_locks.h */
Line 172  ZEND_API zval** zend_get_compiled_variable_value(const Line 172  ZEND_API zval** zend_get_compiled_variable_value(const
         return execute_data_ptr->CVs[var];          return execute_data_ptr->CVs[var];
 }  }
   
static zend_always_inline zval *_get_zval_ptr_tmp(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
 {  {
        return should_free->var = &T(node->u.var).tmp_var;        return should_free->var = &T(var).tmp_var;
 }  }
   
static zval *_get_zval_ptr_var_string_offset(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
 {  {
        temp_variable *T = &T(node->u.var);        zval *ptr = T(var).var.ptr;
        zval *str = T->str_offset.str; 
        zval *ptr; 
   
        /* string offset */        PZVAL_UNLOCK(ptr, should_free);
        ALLOC_ZVAL(ptr); 
        T->str_offset.ptr = ptr; 
        should_free->var = ptr; 
 
        if (T->str_offset.str->type != IS_STRING 
                || ((int)T->str_offset.offset < 0) 
                || (T->str_offset.str->value.str.len <= (int)T->str_offset.offset)) { 
                ptr->value.str.val = STR_EMPTY_ALLOC(); 
                ptr->value.str.len = 0; 
        } else { 
                ptr->value.str.val = estrndup(str->value.str.val + T->str_offset.offset, 1); 
                ptr->value.str.len = 1; 
        } 
        PZVAL_UNLOCK_FREE(str); 
        Z_SET_REFCOUNT_P(ptr, 1); 
        Z_SET_ISREF_P(ptr); 
        ptr->type = IS_STRING; 
         return ptr;          return ptr;
 }  }
   
static zend_always_inline zval *_get_zval_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)
 {  {
         zval *ptr = T(node->u.var).var.ptr;  
         if (EXPECTED(ptr != NULL)) {  
                 PZVAL_UNLOCK(ptr, should_free);  
                 return ptr;  
         } else {  
                 return _get_zval_ptr_var_string_offset(node, Ts, should_free TSRMLS_CC);  
         }  
 }  
   
 static zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var, int type TSRMLS_DC)  
 {  
         zend_compiled_variable *cv = &CV_DEF_OF(var);          zend_compiled_variable *cv = &CV_DEF_OF(var);
   
         if (!EG(active_symbol_table) ||          if (!EG(active_symbol_table) ||
Line 246  static zval **_get_zval_cv_lookup(zval ***ptr, zend_ui Line 216  static zval **_get_zval_cv_lookup(zval ***ptr, zend_ui
         return *ptr;          return *ptr;
 }  }
   
static zend_always_inline zval *_get_zval_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC)static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_R(zval ***ptr, zend_uint var TSRMLS_DC)
 {  {
        zval ***ptr = &CV_OF(node->u.var);        zend_compiled_variable *cv = &CV_DEF_OF(var);
   
           if (!EG(active_symbol_table) ||
               zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                   zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
                   return &EG(uninitialized_zval_ptr);
           }
           return *ptr;
   }
   
   static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_UNSET(zval ***ptr, zend_uint var TSRMLS_DC)
   {
           zend_compiled_variable *cv = &CV_DEF_OF(var);
   
           if (!EG(active_symbol_table) ||
               zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                   zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
                   return &EG(uninitialized_zval_ptr);
           }
           return *ptr;
   }
   
   static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_IS(zval ***ptr, zend_uint var TSRMLS_DC)
   {
           zend_compiled_variable *cv = &CV_DEF_OF(var);
   
           if (!EG(active_symbol_table) ||
               zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                   return &EG(uninitialized_zval_ptr);
           }
           return *ptr;
   }
   
   static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_RW(zval ***ptr, zend_uint var TSRMLS_DC)
   {
           zend_compiled_variable *cv = &CV_DEF_OF(var);
   
           if (!EG(active_symbol_table)) {
                   Z_ADDREF(EG(uninitialized_zval));
                   *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
                   **ptr = &EG(uninitialized_zval);
                   zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
           } else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                   Z_ADDREF(EG(uninitialized_zval));
                   zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
                   zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
           }
           return *ptr;
   }
   
   static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_W(zval ***ptr, zend_uint var TSRMLS_DC)
   {
           zend_compiled_variable *cv = &CV_DEF_OF(var);
   
           if (!EG(active_symbol_table)) {
                   Z_ADDREF(EG(uninitialized_zval));
                   *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
                   **ptr = &EG(uninitialized_zval);
           } else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                   Z_ADDREF(EG(uninitialized_zval));
                   zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
           }
           return *ptr;
   }
   
   static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC)
   {
           zval ***ptr = &CV_OF(var);
   
         if (UNEXPECTED(*ptr == NULL)) {          if (UNEXPECTED(*ptr == NULL)) {
                return *_get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);                return *_get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
         }          }
         return **ptr;          return **ptr;
 }  }
   
static inline zval *_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC)
 {  {
           zval ***ptr = &CV(var);
   
           if (UNEXPECTED(*ptr == NULL)) {
                   return *_get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
           }
           return **ptr;
   }
   
   static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC)
   {
           zval ***ptr = &CV(var);
   
           if (UNEXPECTED(*ptr == NULL)) {
                   return *_get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
           }
           return **ptr;
   }
   
   static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC)
   {
           zval ***ptr = &CV(var);
   
           if (UNEXPECTED(*ptr == NULL)) {
                   return *_get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
           }
           return **ptr;
   }
   
   static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC)
   {
           zval ***ptr = &CV(var);
   
           if (UNEXPECTED(*ptr == NULL)) {
                   return *_get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
           }
           return **ptr;
   }
   
   static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC)
   {
           zval ***ptr = &CV(var);
   
           if (UNEXPECTED(*ptr == NULL)) {
                   return *_get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
           }
           return **ptr;
   }
   
   static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
   {
 /*      should_free->is_var = 0; */  /*      should_free->is_var = 0; */
        switch (node->op_type) {        switch (op_type) {
                 case IS_CONST:                  case IS_CONST:
                         should_free->var = 0;                          should_free->var = 0;
                        return &node->u.constant;                        return node->zv;
                         break;                          break;
                 case IS_TMP_VAR:                  case IS_TMP_VAR:
                        should_free->var = TMP_FREE(&T(node->u.var).tmp_var);                        should_free->var = TMP_FREE(&T(node->var).tmp_var);
                        return &T(node->u.var).tmp_var;                        return &T(node->var).tmp_var;
                         break;                          break;
                 case IS_VAR:                  case IS_VAR:
                        return _get_zval_ptr_var(node, Ts, should_free TSRMLS_CC);                        return _get_zval_ptr_var(node->var, Ts, should_free TSRMLS_CC);
                         break;                          break;
                 case IS_UNUSED:                  case IS_UNUSED:
                         should_free->var = 0;                          should_free->var = 0;
Line 277  static inline zval *_get_zval_ptr(znode *node, const t Line 364  static inline zval *_get_zval_ptr(znode *node, const t
                         break;                          break;
                 case IS_CV:                  case IS_CV:
                         should_free->var = 0;                          should_free->var = 0;
                        return _get_zval_ptr_cv(node, Ts, type TSRMLS_CC);                        return _get_zval_ptr_cv(node->var, type TSRMLS_CC);
                         break;                          break;
                 EMPTY_SWITCH_DEFAULT_CASE()                  EMPTY_SWITCH_DEFAULT_CASE()
         }          }
         return NULL;          return NULL;
 }  }
   
static zend_always_inline zval **_get_zval_ptr_ptr_var(const znode *node, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
 {  {
        zval** ptr_ptr = T(node->u.var).var.ptr_ptr;        zval** ptr_ptr = T(var).var.ptr_ptr;
   
         if (EXPECTED(ptr_ptr != NULL)) {          if (EXPECTED(ptr_ptr != NULL)) {
                 PZVAL_UNLOCK(*ptr_ptr, should_free);                  PZVAL_UNLOCK(*ptr_ptr, should_free);
         } else {          } else {
                 /* string offset */                  /* string offset */
                PZVAL_UNLOCK(T(node->u.var).str_offset.str, should_free);                PZVAL_UNLOCK(T(var).str_offset.str, should_free);
         }          }
         return ptr_ptr;          return ptr_ptr;
 }  }
   
static zend_always_inline zval **_get_zval_ptr_ptr_cv(const znode *node, const temp_variable *Ts, int type TSRMLS_DC)static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC)
 {  {
        zval ***ptr = &CV_OF(node->u.var);        zval ***ptr = &CV_OF(var);
   
         if (UNEXPECTED(*ptr == NULL)) {          if (UNEXPECTED(*ptr == NULL)) {
                return _get_zval_cv_lookup(ptr, node->u.var, type TSRMLS_CC);                return _get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
         }          }
         return *ptr;          return *ptr;
 }  }
   
static inline zval **_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC)
 {  {
        if (node->op_type == IS_CV) {        zval ***ptr = &CV(var);
 
         if (UNEXPECTED(*ptr == NULL)) {
                 return _get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
         }
         return *ptr;
 }
 
 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC)
 {
         zval ***ptr = &CV(var);
 
         if (UNEXPECTED(*ptr == NULL)) {
                 return _get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
         }
         return *ptr;
 }
 
 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC)
 {
         zval ***ptr = &CV(var);
 
         if (UNEXPECTED(*ptr == NULL)) {
                 return _get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
         }
         return *ptr;
 }
 
 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC)
 {
         zval ***ptr = &CV(var);
 
         if (UNEXPECTED(*ptr == NULL)) {
                 return _get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
         }
         return *ptr;
 }
 
 static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC)
 {
         zval ***ptr = &CV(var);
 
         if (UNEXPECTED(*ptr == NULL)) {
                 return _get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
         }
         return *ptr;
 }
 
 static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
 {
         if (op_type == IS_CV) {
                 should_free->var = 0;                  should_free->var = 0;
                return _get_zval_ptr_ptr_cv(node, Ts, type TSRMLS_CC);                return _get_zval_ptr_ptr_cv(node->var, type TSRMLS_CC);
        } else if (node->op_type == IS_VAR) {        } else if (op_type == IS_VAR) {
                return _get_zval_ptr_ptr_var(node, Ts, should_free TSRMLS_CC);                return _get_zval_ptr_ptr_var(node->var, Ts, should_free TSRMLS_CC);
         } else {          } else {
                 should_free->var = 0;                  should_free->var = 0;
                 return NULL;                  return NULL;
Line 330  static zend_always_inline zval *_get_obj_zval_ptr_unus Line 467  static zend_always_inline zval *_get_obj_zval_ptr_unus
         }          }
 }  }
   
static inline zval **_get_obj_zval_ptr_ptr(const znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
 {  {
        if (op->op_type == IS_UNUSED) {        if (op_type == IS_UNUSED) {
                 if (EXPECTED(EG(This) != NULL)) {                  if (EXPECTED(EG(This) != NULL)) {
                         /* this should actually never be modified, _ptr_ptr is modified only when                          /* this should actually never be modified, _ptr_ptr is modified only when
                            the object is empty */                             the object is empty */
Line 342  static inline zval **_get_obj_zval_ptr_ptr(const znode Line 479  static inline zval **_get_obj_zval_ptr_ptr(const znode
                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");                          zend_error_noreturn(E_ERROR, "Using $this when not in object context");
                 }                  }
         }          }
        return get_zval_ptr_ptr(op, Ts, should_free, type);        return get_zval_ptr_ptr(op_type, op, Ts, should_free, type);
 }  }
   
 static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)  static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
Line 355  static zend_always_inline zval **_get_obj_zval_ptr_ptr Line 492  static zend_always_inline zval **_get_obj_zval_ptr_ptr
         }          }
 }  }
   
static inline zval *_get_obj_zval_ptr(znode *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
 {  {
        if (op->op_type == IS_UNUSED) {        if (op_type == IS_UNUSED) {
                 if (EXPECTED(EG(This) != NULL)) {                  if (EXPECTED(EG(This) != NULL)) {
                         should_free->var = 0;                          should_free->var = 0;
                         return EG(This);                          return EG(This);
Line 365  static inline zval *_get_obj_zval_ptr(znode *op, const Line 502  static inline zval *_get_obj_zval_ptr(znode *op, const
                         zend_error_noreturn(E_ERROR, "Using $this when not in object context");                          zend_error_noreturn(E_ERROR, "Using $this when not in object context");
                 }                  }
         }          }
        return get_zval_ptr(op, Ts, should_free, type);        return get_zval_ptr(op_type, op, Ts, should_free, type);
 }  }
   
 static inline void zend_switch_free(temp_variable *T, int extended_value TSRMLS_DC)  
 {  
         if (T->var.ptr) {  
                 if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */  
                         Z_DELREF_P(T->var.ptr);  
                 }  
                 zval_ptr_dtor(&T->var.ptr);  
         } else if (!T->var.ptr_ptr) {  
                 /* perform the equivalent of equivalent of a  
                  * quick & silent get_zval_ptr, and FREE_OP  
                  */  
                 PZVAL_UNLOCK_FREE(T->str_offset.str);  
         }  
 }  
   
 static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)  static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)
 {  {
         zval *variable_ptr = *variable_ptr_ptr;          zval *variable_ptr = *variable_ptr_ptr;
         zval *value_ptr = *value_ptr_ptr;          zval *value_ptr = *value_ptr_ptr;
   
        if (variable_ptr == EG(error_zval_ptr) || value_ptr==EG(error_zval_ptr)) {        if (variable_ptr == &EG(error_zval) || value_ptr == &EG(error_zval)) {
                 variable_ptr_ptr = &EG(uninitialized_zval_ptr);                  variable_ptr_ptr = &EG(uninitialized_zval_ptr);
         } else if (variable_ptr != value_ptr) {          } else if (variable_ptr != value_ptr) {
                 if (!PZVAL_IS_REF(value_ptr)) {                  if (!PZVAL_IS_REF(value_ptr)) {
Line 396  static void zend_assign_to_variable_reference(zval **v Line 518  static void zend_assign_to_variable_reference(zval **v
                         Z_DELREF_P(value_ptr);                          Z_DELREF_P(value_ptr);
                         if (Z_REFCOUNT_P(value_ptr)>0) {                          if (Z_REFCOUNT_P(value_ptr)>0) {
                                 ALLOC_ZVAL(*value_ptr_ptr);                                  ALLOC_ZVAL(*value_ptr_ptr);
                                **value_ptr_ptr = *value_ptr;                                ZVAL_COPY_VALUE(*value_ptr_ptr, value_ptr);
                                 value_ptr = *value_ptr_ptr;                                  value_ptr = *value_ptr_ptr;
                                 zendi_zval_copy_ctor(*value_ptr);                                  zendi_zval_copy_ctor(*value_ptr);
                         }                          }
Line 411  static void zend_assign_to_variable_reference(zval **v Line 533  static void zend_assign_to_variable_reference(zval **v
         } else if (!Z_ISREF_P(variable_ptr)) {          } else if (!Z_ISREF_P(variable_ptr)) {
                 if (variable_ptr_ptr == value_ptr_ptr) {                  if (variable_ptr_ptr == value_ptr_ptr) {
                         SEPARATE_ZVAL(variable_ptr_ptr);                          SEPARATE_ZVAL(variable_ptr_ptr);
                } else if (variable_ptr==EG(uninitialized_zval_ptr)                } else if (variable_ptr==&EG(uninitialized_zval)
                         || Z_REFCOUNT_P(variable_ptr)>2) {                          || Z_REFCOUNT_P(variable_ptr)>2) {
                         /* we need to separate */                          /* we need to separate */
                         Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2);                          Z_SET_REFCOUNT_P(variable_ptr, Z_REFCOUNT_P(variable_ptr) - 2);
                         ALLOC_ZVAL(*variable_ptr_ptr);                          ALLOC_ZVAL(*variable_ptr_ptr);
                        **variable_ptr_ptr = *variable_ptr;                        ZVAL_COPY_VALUE(*variable_ptr_ptr, variable_ptr);
                         zval_copy_ctor(*variable_ptr_ptr);                          zval_copy_ctor(*variable_ptr_ptr);
                         *value_ptr_ptr = *variable_ptr_ptr;                          *value_ptr_ptr = *variable_ptr_ptr;
                         Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2);                          Z_SET_REFCOUNT_PP(variable_ptr_ptr, 2);
Line 432  static inline void make_real_object(zval **object_ptr  Line 554  static inline void make_real_object(zval **object_ptr 
                 || (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0)                  || (Z_TYPE_PP(object_ptr) == IS_BOOL && Z_LVAL_PP(object_ptr) == 0)
                 || (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0)                  || (Z_TYPE_PP(object_ptr) == IS_STRING && Z_STRLEN_PP(object_ptr) == 0)
         ) {          ) {
                 zend_error(E_STRICT, "Creating default object from empty value");  
   
                 SEPARATE_ZVAL_IF_NOT_REF(object_ptr);                  SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
                 zval_dtor(*object_ptr);                  zval_dtor(*object_ptr);
                 object_init(*object_ptr);                  object_init(*object_ptr);
                   zend_error(E_WARNING, "Creating default object from empty value");
         }          }
 }  }
   
static inline char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)
 {  {
         *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);          *pce = zend_fetch_class(cur_arg_info->class_name, cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
   
Line 452  static inline char * zend_verify_arg_class_kind(const  Line 573  static inline char * zend_verify_arg_class_kind(const 
         }          }
 }  }
   
static inline int zend_verify_arg_error(const zend_function *zf, zend_uint arg_num, const zend_arg_info *cur_arg_info, const char *need_msg, const char *need_kind, const char *given_msg, char *given_kind TSRMLS_DC)ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend_uint arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind TSRMLS_DC)
 {  {
         zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;          zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
        char *fname = zf->common.function_name;        const char *fname = zf->common.function_name;
         char *fsep;          char *fsep;
        char *fclass;        const char *fclass;
   
         if (zf->common.scope) {          if (zf->common.scope) {
                 fsep =  "::";                  fsep =  "::";
Line 468  static inline int zend_verify_arg_error(const zend_fun Line 589  static inline int zend_verify_arg_error(const zend_fun
         }          }
   
         if (ptr && ptr->op_array) {          if (ptr && ptr->op_array) {
                zend_error(E_RECOVERABLE_ERROR, "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->op_array->filename, ptr->opline->lineno);                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->op_array->filename, ptr->opline->lineno);
         } else {          } else {
                zend_error(E_RECOVERABLE_ERROR, "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);                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);
         }          }
         return 0;          return 0;
 }  }
Line 493  static inline int zend_verify_arg_type(zend_function * Line 614  static inline int zend_verify_arg_type(zend_function *
   
                 if (!arg) {                  if (!arg) {
                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);                          need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
                        return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "none", "" TSRMLS_CC);                        return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "none", "" TSRMLS_CC);
                 }                  }
                 if (Z_TYPE_P(arg) == IS_OBJECT) {                  if (Z_TYPE_P(arg) == IS_OBJECT) {
                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);                          need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
                         if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {                          if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
                                return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);                                return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
                         }                          }
                 } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {                  } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
                         need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);                          need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
                        return zend_verify_arg_error(zf, arg_num, cur_arg_info, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);                        return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
                 }                  }
        } else if (cur_arg_info->array_type_hint) {        } else if (cur_arg_info->type_hint) {
                if (!arg) {                switch(cur_arg_info->type_hint) {
                        return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", "none", "" TSRMLS_CC);                        case IS_ARRAY:
                                 if (!arg) {
                                         return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC);
                                 }
 
                                 if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
                                         return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
                                 }
                                 break;
 
                         case IS_CALLABLE:
                                 if (!arg) {
                                         return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "" TSRMLS_CC);
                                 }
                                 if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
                                         return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "" TSRMLS_CC);
                                 }
                                 break;
 
                         default:
                                 zend_error(E_ERROR, "Unknown typehint");
                 }                  }
                 if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {  
                         return zend_verify_arg_error(zf, arg_num, cur_arg_info, "be an array", "", zend_zval_type_name(arg), "" TSRMLS_CC);  
                 }  
         }          }
         return 1;          return 1;
 }  }
   
static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval *property_name, znode *value_op, const temp_variable *Ts, int opcode TSRMLS_DC)static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const temp_variable *Ts, int opcode, const zend_literal *key TSRMLS_DC)
 
 {  {
         zval *object = *object_ptr;          zval *object = *object_ptr;
         zend_free_op free_value;          zend_free_op free_value;
        zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R);        zval *value = get_zval_ptr(value_type, value_op, Ts, &free_value, BP_VAR_R);
        zval **retval = &T(result->u.var).var.ptr; 
   
         if (Z_TYPE_P(object) != IS_OBJECT) {          if (Z_TYPE_P(object) != IS_OBJECT) {
                if (object == EG(error_zval_ptr)) {                if (object == &EG(error_zval)) {
                        if (!RETURN_VALUE_UNUSED(result)) {                        if (retval) {
                                *retval = EG(uninitialized_zval_ptr);                                *retval = &EG(uninitialized_zval);
                                 PZVAL_LOCK(*retval);                                  PZVAL_LOCK(*retval);
                         }                          }
                         FREE_OP(free_value);                          FREE_OP(free_value);
Line 538  static inline void zend_assign_to_object(znode *result Line 674  static inline void zend_assign_to_object(znode *result
                         SEPARATE_ZVAL_IF_NOT_REF(object_ptr);                          SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
                         object = *object_ptr;                          object = *object_ptr;
                         Z_ADDREF_P(object);                          Z_ADDREF_P(object);
                        zend_error(E_STRICT, "Creating default object from empty value");                        zend_error(E_WARNING, "Creating default object from empty value");
                         if (Z_REFCOUNT_P(object) == 1) {                          if (Z_REFCOUNT_P(object) == 1) {
                                 /* object was removed by error handler, nothing to assign to */                                  /* object was removed by error handler, nothing to assign to */
                                 zval_ptr_dtor(&object);                                  zval_ptr_dtor(&object);
Line 554  static inline void zend_assign_to_object(znode *result Line 690  static inline void zend_assign_to_object(znode *result
                         object_init(object);                          object_init(object);
                 } else {                  } else {
                         zend_error(E_WARNING, "Attempt to assign property of non-object");                          zend_error(E_WARNING, "Attempt to assign property of non-object");
                        if (!RETURN_VALUE_UNUSED(result)) {                        if (retval) {
                                *retval = EG(uninitialized_zval_ptr);                                *retval = &EG(uninitialized_zval);
                                 PZVAL_LOCK(*retval);                                  PZVAL_LOCK(*retval);
                         }                          }
                         FREE_OP(free_value);                          FREE_OP(free_value);
                         return;                          return;
                 }                  }
         }          }
        
         /* separate our value if necessary */          /* separate our value if necessary */
        if (value_op->op_type == IS_TMP_VAR) {        if (value_type == IS_TMP_VAR) {
                 zval *orig_value = value;                  zval *orig_value = value;
   
                 ALLOC_ZVAL(value);                  ALLOC_ZVAL(value);
                *value = *orig_value;                ZVAL_COPY_VALUE(value, orig_value);
                 Z_UNSET_ISREF_P(value);                  Z_UNSET_ISREF_P(value);
                 Z_SET_REFCOUNT_P(value, 0);                  Z_SET_REFCOUNT_P(value, 0);
        } else if (value_op->op_type == IS_CONST) {        } else if (value_type == IS_CONST) {
                 zval *orig_value = value;                  zval *orig_value = value;
   
                 ALLOC_ZVAL(value);                  ALLOC_ZVAL(value);
                *value = *orig_value;                ZVAL_COPY_VALUE(value, orig_value);
                 Z_UNSET_ISREF_P(value);                  Z_UNSET_ISREF_P(value);
                 Z_SET_REFCOUNT_P(value, 0);                  Z_SET_REFCOUNT_P(value, 0);
                 zval_copy_ctor(value);                  zval_copy_ctor(value);
Line 586  static inline void zend_assign_to_object(znode *result Line 722  static inline void zend_assign_to_object(znode *result
         if (opcode == ZEND_ASSIGN_OBJ) {          if (opcode == ZEND_ASSIGN_OBJ) {
                 if (!Z_OBJ_HT_P(object)->write_property) {                  if (!Z_OBJ_HT_P(object)->write_property) {
                         zend_error(E_WARNING, "Attempt to assign property of non-object");                          zend_error(E_WARNING, "Attempt to assign property of non-object");
                        if (!RETURN_VALUE_UNUSED(result)) {                        if (retval) {
                                *retval = EG(uninitialized_zval_ptr);                                *retval = &EG(uninitialized_zval);
                                PZVAL_LOCK(*retval);                                PZVAL_LOCK(&EG(uninitialized_zval));
                         }                          }
                        if (value_op->op_type == IS_TMP_VAR) {                        if (value_type == IS_TMP_VAR) {
                                 FREE_ZVAL(value);                                  FREE_ZVAL(value);
                        } else if (value_op->op_type == IS_CONST) {                        } else if (value_type == IS_CONST) {
                                 zval_ptr_dtor(&value);                                  zval_ptr_dtor(&value);
                         }                          }
                         FREE_OP(free_value);                          FREE_OP(free_value);
                         return;                          return;
                 }                  }
                Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);                Z_OBJ_HT_P(object)->write_property(object, property_name, value, key TSRMLS_CC);
         } else {          } else {
                 /* Note:  property_name in this case is really the array index! */                  /* Note:  property_name in this case is really the array index! */
                 if (!Z_OBJ_HT_P(object)->write_dimension) {                  if (!Z_OBJ_HT_P(object)->write_dimension) {
Line 607  static inline void zend_assign_to_object(znode *result Line 743  static inline void zend_assign_to_object(znode *result
                 Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);                  Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
         }          }
   
        if (!RETURN_VALUE_UNUSED(result) && !EG(exception)) {        if (retval && !EG(exception)) {
                AI_SET_PTR(T(result->u.var).var, value);                *retval = value;
                 PZVAL_LOCK(value);                  PZVAL_LOCK(value);
         }          }
         zval_ptr_dtor(&value);          zval_ptr_dtor(&value);
Line 625  static inline int zend_assign_to_string_offset(const t Line 761  static inline int zend_assign_to_string_offset(const t
                 }                  }
   
                 if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {                  if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
                        Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);                        if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
                                 char *tmp = (char *) emalloc(T->str_offset.offset+1+1);
 
                                 memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str)+1);
                                 Z_STRVAL_P(T->str_offset.str) = tmp;
                         } else {
                                 Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
                         }
                         memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),                          memset(Z_STRVAL_P(T->str_offset.str) + Z_STRLEN_P(T->str_offset.str),
                                ' ',                                 ' ',
                                T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));                                 T->str_offset.offset - Z_STRLEN_P(T->str_offset.str));
                         Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;                          Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset+1] = 0;
                         Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;                          Z_STRLEN_P(T->str_offset.str) = T->str_offset.offset+1;
                   } else if (IS_INTERNED(Z_STRVAL_P(T->str_offset.str))) {
                           char *tmp = (char *) emalloc(Z_STRLEN_P(T->str_offset.str) + 1);
   
                           memcpy(tmp, Z_STRVAL_P(T->str_offset.str), Z_STRLEN_P(T->str_offset.str) + 1);
                           Z_STRVAL_P(T->str_offset.str) = tmp;
                 }                  }
   
                 if (Z_TYPE_P(value) != IS_STRING) {                  if (Z_TYPE_P(value) != IS_STRING) {
                        zval tmp = *value;                        zval tmp;
   
                           ZVAL_COPY_VALUE(&tmp, value);
                         if (value_type != IS_TMP_VAR) {                          if (value_type != IS_TMP_VAR) {
                                 zval_copy_ctor(&tmp);                                  zval_copy_ctor(&tmp);
                         }                          }
Line 659  static inline int zend_assign_to_string_offset(const t Line 808  static inline int zend_assign_to_string_offset(const t
         return 1;          return 1;
 }  }
   
static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value, int is_tmp_var TSRMLS_DC)
 static inline zval* zend_assign_tmp_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
 {  {
         zval *variable_ptr = *variable_ptr_ptr;          zval *variable_ptr = *variable_ptr_ptr;
         zval garbage;          zval garbage;
   
        if (variable_ptr == EG(error_zval_ptr)) {        if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
                if (is_tmp_var) {            UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
                        zval_dtor(value);                Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
                 return variable_ptr;
         }
 
         if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) &&
             EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
             /* we need to split */
                 Z_DELREF_P(variable_ptr);
                 GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
                 ALLOC_ZVAL(variable_ptr);
                 INIT_PZVAL_COPY(variable_ptr, value);
                 *variable_ptr_ptr = variable_ptr;
                 return variable_ptr;
         } else {
                 if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
                         /* nothing to destroy */
                         ZVAL_COPY_VALUE(variable_ptr, value);
                 } else {
                         ZVAL_COPY_VALUE(&garbage, variable_ptr);
                         ZVAL_COPY_VALUE(variable_ptr, value);
                         _zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
                 }                  }
                return EG(uninitialized_zval_ptr);                return variable_ptr;
         }          }
   }
   
        if (Z_TYPE_P(variable_ptr) == IS_OBJECT && Z_OBJ_HANDLER_P(variable_ptr, set)) {static inline zval* zend_assign_const_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
 {
         zval *variable_ptr = *variable_ptr_ptr;
         zval garbage;
 
         if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
             UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
                 Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);                  Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
                 return variable_ptr;                  return variable_ptr;
         }          }
   
        if (PZVAL_IS_REF(variable_ptr)) {        if (UNEXPECTED(Z_REFCOUNT_P(variable_ptr) > 1) &&
                if (variable_ptr!=value) {            EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
                        zend_uint refcount = Z_REFCOUNT_P(variable_ptr);                /* we need to split */
                Z_DELREF_P(variable_ptr);
                        garbage = *variable_ptr;                GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
                        *variable_ptr = *value;                ALLOC_ZVAL(variable_ptr);
                        Z_SET_REFCOUNT_P(variable_ptr, refcount);                INIT_PZVAL_COPY(variable_ptr, value);
                        Z_SET_ISREF_P(variable_ptr);                zval_copy_ctor(variable_ptr);
                        if (!is_tmp_var) {                *variable_ptr_ptr = variable_ptr;
                                zendi_zval_copy_ctor(*variable_ptr);                return variable_ptr;
                        }        } else {
                        zendi_zval_dtor(garbage);                if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
                        return variable_ptr;                        /* nothing to destroy */
                         ZVAL_COPY_VALUE(variable_ptr, value);
                         zendi_zval_copy_ctor(*variable_ptr);
                 } else {
                         ZVAL_COPY_VALUE(&garbage, variable_ptr);
                         ZVAL_COPY_VALUE(variable_ptr, value);
                         zendi_zval_copy_ctor(*variable_ptr);
                         _zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
                 }                  }
        } else {                return variable_ptr;
                if (Z_DELREF_P(variable_ptr)==0) {        }
                        if (!is_tmp_var) {}
                                if (variable_ptr==value) {
                                        Z_ADDREF_P(variable_ptr);static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value TSRMLS_DC)
                                } else if (PZVAL_IS_REF(value)) {{
                                        garbage = *variable_ptr;        zval *variable_ptr = *variable_ptr_ptr;
                                        *variable_ptr = *value;        zval garbage;
                                        INIT_PZVAL(variable_ptr);
                                        zval_copy_ctor(variable_ptr);        if (Z_TYPE_P(variable_ptr) == IS_OBJECT &&
                                        zendi_zval_dtor(garbage);            UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) {
                                        return variable_ptr;                Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
                 return variable_ptr;
         }
 
         if (EXPECTED(!PZVAL_IS_REF(variable_ptr))) {
                 if (Z_REFCOUNT_P(variable_ptr)==1) {
                         if (UNEXPECTED(variable_ptr == value)) {
                                 return variable_ptr;
                         } else if (EXPECTED(!PZVAL_IS_REF(value))) {
                                 Z_ADDREF_P(value);
                                 *variable_ptr_ptr = value;
                                 if (EXPECTED(variable_ptr != &EG(uninitialized_zval))) {
                                         GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
                                         zval_dtor(variable_ptr);
                                         efree(variable_ptr);
                                 } else {                                  } else {
                                        Z_ADDREF_P(value);                                        Z_DELREF_P(variable_ptr);
                                        *variable_ptr_ptr = value; 
                                        if (variable_ptr != &EG(uninitialized_zval)) { 
                                                GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr); 
                                                zval_dtor(variable_ptr); 
                                                efree(variable_ptr); 
                                        } 
                                        return value; 
                                 }                                  }
                                   return value;
                         } else {                          } else {
                                garbage = *variable_ptr;                                goto copy_value;
                                *variable_ptr = *value; 
                                INIT_PZVAL(variable_ptr); 
                                zendi_zval_dtor(garbage); 
                                return variable_ptr; 
                         }                          }
                 } else { /* we need to split */                  } else { /* we need to split */
                        GC_ZVAL_CHECK_POSSIBLE_ROOT(*variable_ptr_ptr);                        Z_DELREF_P(variable_ptr);
                        if (!is_tmp_var) {                        GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr);
                                if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {                        if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
                                        ALLOC_ZVAL(variable_ptr);                                ALLOC_ZVAL(variable_ptr);
                                        *variable_ptr_ptr = variable_ptr;                                *variable_ptr_ptr = variable_ptr;
                                        *variable_ptr = *value;                                INIT_PZVAL_COPY(variable_ptr, value);
                                        Z_SET_REFCOUNT_P(variable_ptr, 1);                                zval_copy_ctor(variable_ptr);
                                        zval_copy_ctor(variable_ptr);                                return variable_ptr;
                                } else { 
                                        *variable_ptr_ptr = value; 
                                        Z_ADDREF_P(value); 
                                } 
                         } else {                          } else {
                                ALLOC_ZVAL(*variable_ptr_ptr);                                *variable_ptr_ptr = value;
                                Z_SET_REFCOUNT_P(value, 1);                                Z_ADDREF_P(value);
                                **variable_ptr_ptr = *value;                                Z_UNSET_ISREF_P(value);
                                 return value;
                         }                          }
                 }                  }
                Z_UNSET_ISREF_PP(variable_ptr_ptr);        } else {
                 if (EXPECTED(variable_ptr != value)) {
 copy_value:
                         if (EXPECTED(Z_TYPE_P(variable_ptr) <= IS_BOOL)) {
                                 /* nothing to destroy */
                                 ZVAL_COPY_VALUE(variable_ptr, value);
                                 zendi_zval_copy_ctor(*variable_ptr);
                         } else {
                                 ZVAL_COPY_VALUE(&garbage, variable_ptr);
                                 ZVAL_COPY_VALUE(variable_ptr, value);
                                 zendi_zval_copy_ctor(*variable_ptr);
                                 _zval_dtor_func(&garbage ZEND_FILE_LINE_CC);
                         }
                 }
                 return variable_ptr;
         }          }
   
         return *variable_ptr_ptr;  
 }  }
   
   
 /* Utility Functions for Extensions */  /* Utility Functions for Extensions */
 static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)  static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC)
 {  {
Line 770  static void zend_extension_fcall_end_handler(const zen Line 966  static void zend_extension_fcall_end_handler(const zen
 }  }
   
   
static inline HashTable *zend_get_target_symbol_table(const zend_op *opline, const temp_variable *Ts, int type, const zval *variable TSRMLS_DC)static inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC)
 {  {
        switch (opline->op2.u.EA.type) {        switch (fetch_type) {
                 case ZEND_FETCH_LOCAL:                  case ZEND_FETCH_LOCAL:
                         if (!EG(active_symbol_table)) {                          if (!EG(active_symbol_table)) {
                                 zend_rebuild_symbol_table(TSRMLS_C);                                  zend_rebuild_symbol_table(TSRMLS_C);
Line 795  static inline HashTable *zend_get_target_symbol_table( Line 991  static inline HashTable *zend_get_target_symbol_table(
         return NULL;          return NULL;
 }  }
   
static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int type TSRMLS_DC)static inline zval **zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
 {  {
         zval **retval;          zval **retval;
         char *offset_key;          char *offset_key;
         int offset_key_length;          int offset_key_length;
        long index;        ulong hval;
   
         switch (dim->type) {          switch (dim->type) {
                 case IS_NULL:                  case IS_NULL:
                         offset_key = "";                          offset_key = "";
                         offset_key_length = 0;                          offset_key_length = 0;
                           hval = zend_inline_hash_func("", 1);
                         goto fetch_string_dim;                          goto fetch_string_dim;
   
                 case IS_STRING:                  case IS_STRING:
                        
                         offset_key = dim->value.str.val;                          offset_key = dim->value.str.val;
                         offset_key_length = dim->value.str.len;                          offset_key_length = dim->value.str.len;
                        
                         if (dim_type == IS_CONST) {
                                 hval = Z_HASH_P(dim);
                         } else {
                                 ZEND_HANDLE_NUMERIC_EX(offset_key, offset_key_length+1, hval, goto num_index);
                                 if (IS_INTERNED(offset_key)) {
                                         hval = INTERNED_HASH(offset_key);
                                 } else {
                                         hval = zend_hash_func(offset_key, offset_key_length+1);
                                 }
                         }
 fetch_string_dim:  fetch_string_dim:
                        if (zend_symtable_find(ht, offset_key, offset_key_length+1, (void **) &retval) == FAILURE) {                        if (zend_hash_quick_find(ht, offset_key, offset_key_length+1, hval, (void **) &retval) == FAILURE) {
                                 switch (type) {                                  switch (type) {
                                         case BP_VAR_R:                                          case BP_VAR_R:
                                                 zend_error(E_NOTICE, "Undefined index: %s", offset_key);                                                  zend_error(E_NOTICE, "Undefined index: %s", offset_key);
Line 830  fetch_string_dim: Line 1037  fetch_string_dim:
                                                         zval *new_zval = &EG(uninitialized_zval);                                                          zval *new_zval = &EG(uninitialized_zval);
   
                                                         Z_ADDREF_P(new_zval);                                                          Z_ADDREF_P(new_zval);
                                                        zend_symtable_update(ht, offset_key, offset_key_length+1, &new_zval, sizeof(zval *), (void **) &retval);                                                        zend_hash_quick_update(ht, offset_key, offset_key_length+1, hval, &new_zval, sizeof(zval *), (void **) &retval);
                                                 }                                                  }
                                                 break;                                                  break;
                                 }                                  }
                         }                          }
                         break;                          break;
                 case IS_DOUBLE:                  case IS_DOUBLE:
                        index = zend_dval_to_lval(Z_DVAL_P(dim));                        hval = zend_dval_to_lval(Z_DVAL_P(dim));
                         goto num_index;                          goto num_index;
                 case IS_RESOURCE:                  case IS_RESOURCE:
                         zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));                          zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(dim), Z_LVAL_P(dim));
                         /* Fall Through */                          /* Fall Through */
                 case IS_BOOL:                  case IS_BOOL:
                 case IS_LONG:                  case IS_LONG:
                        index = Z_LVAL_P(dim);                        hval = Z_LVAL_P(dim);
 num_index:  num_index:
                        if (zend_hash_index_find(ht, index, (void **) &retval) == FAILURE) {                        if (zend_hash_index_find(ht, hval, (void **) &retval) == FAILURE) {
                                 switch (type) {                                  switch (type) {
                                         case BP_VAR_R:                                          case BP_VAR_R:
                                                zend_error(E_NOTICE,"Undefined offset: %ld", index);                                                zend_error(E_NOTICE,"Undefined offset: %ld", hval);
                                                 /* break missing intentionally */                                                  /* break missing intentionally */
                                         case BP_VAR_UNSET:                                          case BP_VAR_UNSET:
                                         case BP_VAR_IS:                                          case BP_VAR_IS:
                                                 retval = &EG(uninitialized_zval_ptr);                                                  retval = &EG(uninitialized_zval_ptr);
                                                 break;                                                  break;
                                         case BP_VAR_RW:                                          case BP_VAR_RW:
                                                zend_error(E_NOTICE,"Undefined offset: %ld", index);                                                zend_error(E_NOTICE,"Undefined offset: %ld", hval);
                                                 /* break missing intentionally */                                                  /* break missing intentionally */
                                         case BP_VAR_W: {                                          case BP_VAR_W: {
                                                 zval *new_zval = &EG(uninitialized_zval);                                                  zval *new_zval = &EG(uninitialized_zval);
   
                                                 Z_ADDREF_P(new_zval);                                                  Z_ADDREF_P(new_zval);
                                                zend_hash_index_update(ht, index, &new_zval, sizeof(zval *), (void **) &retval);                                                zend_hash_index_update(ht, hval, &new_zval, sizeof(zval *), (void **) &retval);
                                         }                                          }
                                         break;                                          break;
                                 }                                  }
Line 877  num_index: Line 1084  num_index:
         return retval;          return retval;
 }  }
   
static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)static void zend_fetch_dimension_address(temp_variable *result, zval **container_ptr, zval *dim, int dim_type, int type TSRMLS_DC)
 {  {
         zval *container = *container_ptr;          zval *container = *container_ptr;
         zval **retval;          zval **retval;
Line 900  fetch_from_array: Line 1107  fetch_from_array:
                                         Z_DELREF_P(new_zval);                                          Z_DELREF_P(new_zval);
                                 }                                  }
                         } else {                          } else {
                                retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);                                retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
                         }                          }
                         result->var.ptr_ptr = retval;                          result->var.ptr_ptr = retval;
                         PZVAL_LOCK(*retval);                          PZVAL_LOCK(*retval);
Line 908  fetch_from_array: Line 1115  fetch_from_array:
                         break;                          break;
   
                 case IS_NULL:                  case IS_NULL:
                        if (container == EG(error_zval_ptr)) {                        if (container == &EG(error_zval)) {
                                 result->var.ptr_ptr = &EG(error_zval_ptr);                                  result->var.ptr_ptr = &EG(error_zval_ptr);
                                 PZVAL_LOCK(EG(error_zval_ptr));                                  PZVAL_LOCK(EG(error_zval_ptr));
                         } else if (type != BP_VAR_UNSET) {                          } else if (type != BP_VAR_UNSET) {
Line 938  convert_to_array: Line 1145  convert_to_array:
                                         zend_error_noreturn(E_ERROR, "[] operator not supported for strings");                                          zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
                                 }                                  }
   
                                   if (type != BP_VAR_UNSET) {
                                           SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
                                   }
   
                                 if (Z_TYPE_P(dim) != IS_LONG) {                                  if (Z_TYPE_P(dim) != IS_LONG) {
   
                                         switch(Z_TYPE_P(dim)) {                                          switch(Z_TYPE_P(dim)) {
                                                 /* case IS_LONG: */                                                  /* case IS_LONG: */
                                                 case IS_STRING:                                                  case IS_STRING:
                                                           if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
                                                                   break;
                                                           }
                                                           if (type != BP_VAR_UNSET) {
                                                                   zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val);
                                                           }
   
                                                           break;
                                                 case IS_DOUBLE:                                                  case IS_DOUBLE:
                                                 case IS_NULL:                                                  case IS_NULL:
                                                 case IS_BOOL:                                                  case IS_BOOL:
                                                        /* do nothing */                                                        zend_error(E_NOTICE, "String offset cast occurred");
                                                         break;                                                          break;
                                                 default:                                                  default:
                                                         zend_error(E_WARNING, "Illegal offset type");                                                          zend_error(E_WARNING, "Illegal offset type");
Line 957  convert_to_array: Line 1177  convert_to_array:
                                         convert_to_long(&tmp);                                          convert_to_long(&tmp);
                                         dim = &tmp;                                          dim = &tmp;
                                 }                                  }
                                 if (type != BP_VAR_UNSET) {  
                                         SEPARATE_ZVAL_IF_NOT_REF(container_ptr);  
                                 }  
                                 container = *container_ptr;                                  container = *container_ptr;
                                 result->str_offset.str = container;                                  result->str_offset.str = container;
                                 PZVAL_LOCK(container);                                  PZVAL_LOCK(container);
                                 result->str_offset.offset = Z_LVAL_P(dim);                                  result->str_offset.offset = Z_LVAL_P(dim);
                                result->var.ptr_ptr = NULL;                                result->str_offset.ptr_ptr = NULL;
                                result->var.ptr = NULL; 
                                 return;                                  return;
                         }                          }
                         break;                          break;
Line 976  convert_to_array: Line 1192  convert_to_array:
                         } else {                          } else {
                                 zval *overloaded_result;                                  zval *overloaded_result;
   
                                if (dim_is_tmp_var) {                                if (dim_type == IS_TMP_VAR) {
                                         zval *orig = dim;                                          zval *orig = dim;
                                         MAKE_REAL_ZVAL_PTR(dim);                                          MAKE_REAL_ZVAL_PTR(dim);
                                         ZVAL_NULL(orig);                                          ZVAL_NULL(orig);
Line 989  convert_to_array: Line 1205  convert_to_array:
                                                         zval *tmp = overloaded_result;                                                          zval *tmp = overloaded_result;
   
                                                         ALLOC_ZVAL(overloaded_result);                                                          ALLOC_ZVAL(overloaded_result);
                                                        *overloaded_result = *tmp;                                                        ZVAL_COPY_VALUE(overloaded_result, tmp);
                                                         zval_copy_ctor(overloaded_result);                                                          zval_copy_ctor(overloaded_result);
                                                         Z_UNSET_ISREF_P(overloaded_result);                                                          Z_UNSET_ISREF_P(overloaded_result);
                                                         Z_SET_REFCOUNT_P(overloaded_result, 0);                                                          Z_SET_REFCOUNT_P(overloaded_result, 0);
Line 1003  convert_to_array: Line 1219  convert_to_array:
                                 } else {                                  } else {
                                         retval = &EG(error_zval_ptr);                                          retval = &EG(error_zval_ptr);
                                 }                                  }
                                AI_SET_PTR(result->var, *retval);                                AI_SET_PTR(result, *retval);
                                 PZVAL_LOCK(*retval);                                  PZVAL_LOCK(*retval);
                                if (dim_is_tmp_var) {                                if (dim_type == IS_TMP_VAR) {
                                         zval_ptr_dtor(&dim);                                          zval_ptr_dtor(&dim);
                                 }                                  }
                         }                          }
Line 1021  convert_to_array: Line 1237  convert_to_array:
                 default:                  default:
                         if (type == BP_VAR_UNSET) {                          if (type == BP_VAR_UNSET) {
                                 zend_error(E_WARNING, "Cannot unset offset in a non-array variable");                                  zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
                                AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));                                AI_SET_PTR(result, &EG(uninitialized_zval));
                                PZVAL_LOCK(EG(uninitialized_zval_ptr));                                PZVAL_LOCK(&EG(uninitialized_zval));
                         } else {                          } else {
                                 zend_error(E_WARNING, "Cannot use a scalar value as an array");                                  zend_error(E_WARNING, "Cannot use a scalar value as an array");
                                 result->var.ptr_ptr = &EG(error_zval_ptr);                                  result->var.ptr_ptr = &EG(error_zval_ptr);
Line 1032  convert_to_array: Line 1248  convert_to_array:
         }          }
 }  }
   
static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)static void zend_fetch_dimension_address_read(temp_variable *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
 {  {
         zval *container = *container_ptr;  
         zval **retval;          zval **retval;
   
         switch (Z_TYPE_P(container)) {          switch (Z_TYPE_P(container)) {
   
                 case IS_ARRAY:                  case IS_ARRAY:
                        retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);                        retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
                        if (result) {                        AI_SET_PTR(result, *retval);
                                AI_SET_PTR(result->var, *retval);                        PZVAL_LOCK(*retval);
                                PZVAL_LOCK(*retval); 
                        } 
                         return;                          return;
                         break;  
   
                 case IS_NULL:                  case IS_NULL:
                        if (result) {                        AI_SET_PTR(result, &EG(uninitialized_zval));
                                AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));                        PZVAL_LOCK(&EG(uninitialized_zval));
                                PZVAL_LOCK(EG(uninitialized_zval_ptr)); 
                        } 
                         return;                          return;
                         break;  
   
                 case IS_STRING: {                  case IS_STRING: {
                                 zval tmp;                                  zval tmp;
                                   zval *ptr;
   
                                 if (Z_TYPE_P(dim) != IS_LONG) {                                  if (Z_TYPE_P(dim) != IS_LONG) {
                                         switch(Z_TYPE_P(dim)) {                                          switch(Z_TYPE_P(dim)) {
                                                 /* case IS_LONG: */                                                  /* case IS_LONG: */
                                                 case IS_STRING:                                                  case IS_STRING:
                                                           if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
                                                                   break;
                                                           }
                                                           if (type != BP_VAR_IS) {
                                                                   zend_error(E_WARNING, "Illegal string offset '%s'", dim->value.str.val);
                                                           }
                                                           break;
                                                 case IS_DOUBLE:                                                  case IS_DOUBLE:
                                                 case IS_NULL:                                                  case IS_NULL:
                                                 case IS_BOOL:                                                  case IS_BOOL:
                                                        /* do nothing */                                                        if (type != BP_VAR_IS) {
                                                                 zend_error(E_NOTICE, "String offset cast occurred");
                                                         }
                                                         break;                                                          break;
                                                 default:                                                  default:
                                                         zend_error(E_WARNING, "Illegal offset type");                                                          zend_error(E_WARNING, "Illegal offset type");
                                                         break;                                                          break;
                                         }                                          }
   
                                        tmp = *dim;                                        ZVAL_COPY_VALUE(&tmp, dim);
                                         zval_copy_ctor(&tmp);                                          zval_copy_ctor(&tmp);
                                         convert_to_long(&tmp);                                          convert_to_long(&tmp);
                                         dim = &tmp;                                          dim = &tmp;
                                 }                                  }
                                if (result) {
                                        if ((Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) && type != BP_VAR_IS) {                                ALLOC_ZVAL(ptr);
                                 INIT_PZVAL(ptr);
                                 Z_TYPE_P(ptr) = IS_STRING;
 
                                 if (Z_LVAL_P(dim) < 0 || Z_STRLEN_P(container) <= Z_LVAL_P(dim)) {
                                         if (type != BP_VAR_IS) {
                                                 zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));                                                  zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
                                         }                                          }
                                        result->str_offset.str = container;                                        Z_STRVAL_P(ptr) = STR_EMPTY_ALLOC();
                                        PZVAL_LOCK(container);                                        Z_STRLEN_P(ptr) = 0;
                                        result->str_offset.offset = Z_LVAL_P(dim);                                } else {
                                        result->var.ptr_ptr = NULL;                                        Z_STRVAL_P(ptr) = (char*)emalloc(2);
                                        result->var.ptr = NULL;                                        Z_STRVAL_P(ptr)[0] = Z_STRVAL_P(container)[Z_LVAL_P(dim)];
                                         Z_STRVAL_P(ptr)[1] = 0;
                                         Z_STRLEN_P(ptr) = 1;
                                 }                                  }
                                   AI_SET_PTR(result, ptr);
                                 return;                                  return;
                         }                          }
                         break;                          break;
Line 1098  static void zend_fetch_dimension_address_read(temp_var Line 1325  static void zend_fetch_dimension_address_read(temp_var
                         } else {                          } else {
                                 zval *overloaded_result;                                  zval *overloaded_result;
   
                                if (dim_is_tmp_var) {                                if (dim_type == IS_TMP_VAR) {
                                         zval *orig = dim;                                          zval *orig = dim;
                                         MAKE_REAL_ZVAL_PTR(dim);                                          MAKE_REAL_ZVAL_PTR(dim);
                                         ZVAL_NULL(orig);                                          ZVAL_NULL(orig);
Line 1106  static void zend_fetch_dimension_address_read(temp_var Line 1333  static void zend_fetch_dimension_address_read(temp_var
                                 overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);                                  overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
   
                                 if (overloaded_result) {                                  if (overloaded_result) {
                                        if (result) {                                        AI_SET_PTR(result, overloaded_result);
                                                AI_SET_PTR(result->var, overloaded_result);                                        PZVAL_LOCK(overloaded_result);
                                                PZVAL_LOCK(overloaded_result); 
                                        } else if (Z_REFCOUNT_P(overloaded_result) == 0) { 
                                                /* Destroy unused result from offsetGet() magic method */ 
                                                Z_SET_REFCOUNT_P(overloaded_result, 1); 
                                                zval_ptr_dtor(&overloaded_result); 
                                        } 
                                 } else if (result) {                                  } else if (result) {
                                        AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));                                        AI_SET_PTR(result, &EG(uninitialized_zval));
                                        PZVAL_LOCK(EG(uninitialized_zval_ptr));                                        PZVAL_LOCK(&EG(uninitialized_zval));
                                 }                                  }
                                if (dim_is_tmp_var) {                                if (dim_type == IS_TMP_VAR) {
                                         zval_ptr_dtor(&dim);                                          zval_ptr_dtor(&dim);
                                 }                                  }
                         }                          }
                         return;                          return;
                         break;  
   
                 default:                  default:
                        if (result) {                        AI_SET_PTR(result, &EG(uninitialized_zval));
                                AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));                        PZVAL_LOCK(&EG(uninitialized_zval));
                                PZVAL_LOCK(EG(uninitialized_zval_ptr)); 
                        } 
                         return;                          return;
                         break;  
         }          }
 }  }
   
static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC)static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC)
 {  {
         zval *container = *container_ptr;;          zval *container = *container_ptr;;
   
         if (Z_TYPE_P(container) != IS_OBJECT) {          if (Z_TYPE_P(container) != IS_OBJECT) {
                if (container == EG(error_zval_ptr)) {                if (container == &EG(error_zval)) {
                         result->var.ptr_ptr = &EG(error_zval_ptr);                          result->var.ptr_ptr = &EG(error_zval_ptr);
                        PZVAL_LOCK(*result->var.ptr_ptr);                        PZVAL_LOCK(EG(error_zval_ptr));
                         return;                          return;
                 }                  }
   
Line 1165  static void zend_fetch_property_address(temp_variable  Line 1382  static void zend_fetch_property_address(temp_variable 
         }          }
   
         if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {          if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
                zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr TSRMLS_CC);                zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, key TSRMLS_CC);
                 if (NULL == ptr_ptr) {                  if (NULL == ptr_ptr) {
                         zval *ptr;                          zval *ptr;
   
                         if (Z_OBJ_HT_P(container)->read_property &&                          if (Z_OBJ_HT_P(container)->read_property &&
                                (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC)) != NULL) {                                (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC)) != NULL) {
                                AI_SET_PTR(result->var, ptr);                                AI_SET_PTR(result, ptr);
                                 PZVAL_LOCK(ptr);                                  PZVAL_LOCK(ptr);
                         } else {                          } else {
                                 zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");                                  zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
Line 1181  static void zend_fetch_property_address(temp_variable  Line 1398  static void zend_fetch_property_address(temp_variable 
                         PZVAL_LOCK(*ptr_ptr);                          PZVAL_LOCK(*ptr_ptr);
                 }                  }
         } else if (Z_OBJ_HT_P(container)->read_property) {          } else if (Z_OBJ_HT_P(container)->read_property) {
                zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC);                zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, key TSRMLS_CC);
   
                AI_SET_PTR(result->var, ptr);                AI_SET_PTR(result, ptr);
                 PZVAL_LOCK(ptr);                  PZVAL_LOCK(ptr);
         } else {          } else {
                 zend_error(E_WARNING, "This object doesn't support property references");                  zend_error(E_WARNING, "This object doesn't support property references");
Line 1192  static void zend_fetch_property_address(temp_variable  Line 1409  static void zend_fetch_property_address(temp_variable 
         }          }
 }  }
   
static inline zend_brk_cont_element* zend_brk_cont(const zval *nest_levels_zval, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)
 {  {
        zval tmp;        int original_nest_levels = nest_levels;
        int nest_levels, original_nest_levels; 
         zend_brk_cont_element *jmp_to;          zend_brk_cont_element *jmp_to;
   
         if (nest_levels_zval->type != IS_LONG) {  
                 tmp = *nest_levels_zval;  
                 zval_copy_ctor(&tmp);  
                 convert_to_long(&tmp);  
                 nest_levels = tmp.value.lval;  
         } else {  
                 nest_levels = nest_levels_zval->value.lval;  
         }  
         original_nest_levels = nest_levels;  
         do {          do {
                 if (array_offset==-1) {                  if (array_offset==-1) {
                         zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");                          zend_error_noreturn(E_ERROR, "Cannot break/continue %d level%s", original_nest_levels, (original_nest_levels == 1) ? "" : "s");
Line 1217  static inline zend_brk_cont_element* zend_brk_cont(con Line 1424  static inline zend_brk_cont_element* zend_brk_cont(con
   
                         switch (brk_opline->opcode) {                          switch (brk_opline->opcode) {
                                 case ZEND_SWITCH_FREE:                                  case ZEND_SWITCH_FREE:
                                        if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {                                        if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
                                                zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->extended_value TSRMLS_CC);                                                zval_ptr_dtor(&T(brk_opline->op1.var).var.ptr);
                                         }                                          }
                                         break;                                          break;
                                 case ZEND_FREE:                                  case ZEND_FREE:
                                        if (brk_opline->op1.u.EA.type != EXT_TYPE_FREE_ON_RETURN) {                                        if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
                                                zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var);                                                zendi_zval_dtor(T(brk_opline->op1.var).tmp_var);
                                         }                                          }
                                         break;                                          break;
                         }                          }
Line 1269  ZEND_API opcode_handler_t *zend_opcode_handlers; Line 1476  ZEND_API opcode_handler_t *zend_opcode_handlers;
   
 ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)  ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
 {  {
        zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.u.var)).var.ptr;        zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr;
        ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, execute_data_ptr->function_state.function->common.return_reference?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);        ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);
 }  }
   
 #define ZEND_VM_NEXT_OPCODE() \  #define ZEND_VM_NEXT_OPCODE() \
         CHECK_SYMBOL_TABLES() \          CHECK_SYMBOL_TABLES() \
        EX(opline)++; \        ZEND_VM_INC_OPCODE(); \
         ZEND_VM_CONTINUE()          ZEND_VM_CONTINUE()
   
 #define ZEND_VM_SET_OPCODE(new_op) \  #define ZEND_VM_SET_OPCODE(new_op) \
         CHECK_SYMBOL_TABLES() \          CHECK_SYMBOL_TABLES() \
        EX(opline) = new_op        OPLINE = new_op
   
 #define ZEND_VM_JMP(new_op) \  #define ZEND_VM_JMP(new_op) \
         CHECK_SYMBOL_TABLES() \  
         if (EXPECTED(!EG(exception))) { \          if (EXPECTED(!EG(exception))) { \
                EX(opline) = new_op; \                ZEND_VM_SET_OPCODE(new_op); \
         } else { \
                 LOAD_OPLINE(); \
         } \          } \
         ZEND_VM_CONTINUE()          ZEND_VM_CONTINUE()
   
 #define ZEND_VM_INC_OPCODE() \  #define ZEND_VM_INC_OPCODE() \
        EX(opline)++        OPLINE++
   
   #ifdef __GNUC__
   # define ZEND_VM_GUARD(name) __asm__("#" #name)
   #else
   # define ZEND_VM_GUARD(name)
   #endif
   
 #include "zend_vm_execute.h"  #include "zend_vm_execute.h"
   
 ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)  ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
 {  {
         if (opcode != ZEND_USER_OPCODE) {          if (opcode != ZEND_USER_OPCODE) {
                zend_user_opcodes[opcode] = ZEND_USER_OPCODE;                if (handler == NULL) {
                         /* restore the original handler */                      
                         zend_user_opcodes[opcode] = opcode;
                 } else {
                         zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
                 }
                 zend_user_opcode_handlers[opcode] = handler;                  zend_user_opcode_handlers[opcode] = handler;
                 return SUCCESS;                  return SUCCESS;
         }          }
Line 1309  ZEND_API user_opcode_handler_t zend_get_user_opcode_ha Line 1528  ZEND_API user_opcode_handler_t zend_get_user_opcode_ha
         return zend_user_opcode_handlers[opcode];          return zend_user_opcode_handlers[opcode];
 }  }
   
ZEND_API zval *zend_get_zval_ptr(znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
        return get_zval_ptr(node, Ts, should_free, type);        return get_zval_ptr(op_type, node, Ts, should_free, type);
 }  }
   
ZEND_API zval **zend_get_zval_ptr_ptr(const znode *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
        return get_zval_ptr_ptr(node, Ts, should_free, type);        return get_zval_ptr_ptr(op_type, node, Ts, should_free, type);
 }  }
   
 /*  /*

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>