]> granicus.if.org Git - php/commitdiff
executor optimization
authorDmitry Stogov <dmitry@php.net>
Fri, 14 Dec 2007 14:14:50 +0000 (14:14 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 14 Dec 2007 14:14:50 +0000 (14:14 +0000)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 508cc974c5dbb97c26afd13d6c91fad3cf7c9c11..5d4145762345144fb6c3c92629a2d287fbdf1a2f 100644 (file)
@@ -102,6 +102,10 @@ static inline void zend_pzval_unlock_free_func(zval *z)
                (ai).ptr = NULL; \
        }
 
+#define AI_SET_PTR(ai, val)            \
+       (ai).ptr = (val);                       \
+       (ai).ptr_ptr = &((ai).ptr);
+
 #define FREE_OP(should_free) \
        if (should_free.var) { \
                if ((zend_uintptr_t)should_free.var & 1L) { \
@@ -198,9 +202,7 @@ static inline zval *_get_zval_ptr_var(znode *node, temp_variable *Ts, zend_free_
                        ptr->value.str.val = STR_EMPTY_ALLOC();
                        ptr->value.str.len = 0;
                } else {
-                       char c = str->value.str.val[T->str_offset.offset];
-
-                       ptr->value.str.val = estrndup(&c, 1);
+                       ptr->value.str.val = estrndup(str->value.str.val + T->str_offset.offset, 1);
                        ptr->value.str.len = 1;
                }
                PZVAL_UNLOCK_FREE(str);
@@ -367,27 +369,22 @@ static inline zval *_get_obj_zval_ptr(znode *op, temp_variable *Ts, zend_free_op
        return get_zval_ptr(op, Ts, should_free, type);
 }
 
-static inline void zend_switch_free(zend_op *opline, temp_variable *Ts TSRMLS_DC)
+static inline void zend_switch_free(temp_variable *T, int type, int extended_value TSRMLS_DC)
 {
-       switch (opline->op1.op_type) {
-               case IS_VAR:
-                       if (!T(opline->op1.u.var).var.ptr_ptr) {
-                               temp_variable *T = &T(opline->op1.u.var);
-                               /* perform the equivalent of equivalent of a
-                                * quick & silent get_zval_ptr, and FREE_OP
-                                */
-                               PZVAL_UNLOCK_FREE(T->str_offset.str);
-                       } else if (T(opline->op1.u.var).var.ptr) {
-                               zval_ptr_dtor(&T(opline->op1.u.var).var.ptr);
-                               if (opline->extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */
-                                       zval_ptr_dtor(&T(opline->op1.u.var).var.ptr);
-                               }
+       if (type == IS_VAR) {
+               if (T->var.ptr) {
+                       if (extended_value & ZEND_FE_RESET_VARIABLE) { /* foreach() free */
+                               Z_DELREF_P(T->var.ptr);
                        }
-                       break;
-               case IS_TMP_VAR:
-                       zendi_zval_dtor(T(opline->op1.u.var).tmp_var);
-                       break;
-               EMPTY_SWITCH_DEFAULT_CASE()
+                       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);
+               }
+       } else { /* IS_TMP_VAR */
+               zendi_zval_dtor(T->tmp_var);
        }
 }
 
@@ -532,11 +529,10 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
 }
 
 
-static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode *op2, znode *value_op, temp_variable *Ts, int opcode TSRMLS_DC)
+static inline void zend_assign_to_object(znode *result, zval **object_ptr, zval *property_name, znode *value_op, temp_variable *Ts, int opcode TSRMLS_DC)
 {
        zval *object;
-       zend_free_op free_op2, free_value;
-       zval *property_name = get_zval_ptr(op2, Ts, &free_op2, BP_VAR_R);
+       zend_free_op free_value;
        zval *value = get_zval_ptr(value_op, Ts, &free_value, BP_VAR_R);
        zval **retval = &T(result->u.var).var.ptr;
 
@@ -544,31 +540,35 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
 
-       if (*object_ptr == EG(error_zval_ptr)) {
-               FREE_OP(free_op2);
-               if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+       if (Z_TYPE_P(*object_ptr) != IS_OBJECT) {
+               if (*object_ptr == EG(error_zval_ptr)) {
+                       if (!RETURN_VALUE_UNUSED(result)) {
+                               *retval = EG(uninitialized_zval_ptr);
+                               PZVAL_LOCK(*retval);
+                       }
+                       FREE_OP(free_value);
+                       return;
                }
-               FREE_OP(free_value);
-               return;
-       }
-
-       make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
-       object = *object_ptr;
-
-       if (Z_TYPE_P(object) != IS_OBJECT || (opcode == ZEND_ASSIGN_OBJ && !Z_OBJ_HT_P(object)->write_property)) {
-               zend_error(E_WARNING, "Attempt to assign property of non-object");
-               FREE_OP(free_op2);
-               if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+               if (Z_TYPE_PP(object_ptr) == IS_NULL ||
+                   (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)) {
+                       zend_error(E_STRICT, "Creating default object from empty value");
+                       SEPARATE_ZVAL_IF_NOT_REF(object_ptr);
+                       zval_dtor(*object_ptr);
+                       object_init(*object_ptr);
+               } else {
+                       zend_error(E_WARNING, "Attempt to assign property of non-object");
+                       if (!RETURN_VALUE_UNUSED(result)) {
+                               *retval = EG(uninitialized_zval_ptr);
+                               PZVAL_LOCK(*retval);
+                       }
+                       FREE_OP(free_value);
+                       return;
                }
-               FREE_OP(free_value);
-               return;
        }
        
        /* here we are sure we are dealing with an object */
+       object = *object_ptr;
 
        /* separate our value if necessary */
        if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
@@ -610,8 +610,14 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
 
        Z_ADDREF_P(value);
        if (opcode == ZEND_ASSIGN_OBJ) {
-               if (IS_TMP_FREE(free_op2)) {
-                       MAKE_REAL_ZVAL_PTR(property_name);
+               if (!Z_OBJ_HT_P(object)->write_property) {
+                       zend_error(E_WARNING, "Attempt to assign property of non-object");
+                       if (!RETURN_VALUE_UNUSED(result)) {
+                               *retval = EG(uninitialized_zval_ptr);
+                               PZVAL_LOCK(*retval);
+                       }
+                       FREE_OP(free_value);
+                       return;
                }
                Z_OBJ_HT_P(object)->write_property(object, property_name, value TSRMLS_CC);
        } else {
@@ -619,118 +625,83 @@ static inline void zend_assign_to_object(znode *result, zval **object_ptr, znode
                if (!Z_OBJ_HT_P(object)->write_dimension) {
                        zend_error_noreturn(E_ERROR, "Cannot use object as array");
                }
-               if (IS_TMP_FREE(free_op2)) {
-                       MAKE_REAL_ZVAL_PTR(property_name);
-               }
                Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC);
        }
 
-       if (result && !RETURN_VALUE_UNUSED(result) && !EG(exception)) {
-               T(result->u.var).var.ptr = value;
-               T(result->u.var).var.ptr_ptr = &T(result->u.var).var.ptr; /* this is so that we could use it in FETCH_DIM_R, etc. - see bug #27876 */
+       if (!RETURN_VALUE_UNUSED(result) && !EG(exception)) {
+               AI_SET_PTR(T(result->u.var).var, value);
                PZVAL_LOCK(value);
        }
-       if (IS_TMP_FREE(free_op2)) {
-               zval_ptr_dtor(&property_name);
-       } else {
-               FREE_OP(free_op2);
-       }
        zval_ptr_dtor(&value);
        FREE_OP_IF_VAR(free_value);
 }
 
-
-static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2, zval *value, int type, temp_variable *Ts TSRMLS_DC)
+static inline void zend_assign_to_string_offset(temp_variable *T, zval *value, int value_type TSRMLS_DC)
 {
-       zend_free_op free_op1;
-       zval **variable_ptr_ptr = get_zval_ptr_ptr(op1, Ts, &free_op1, BP_VAR_W);
-       zval *variable_ptr;
-
-       if (!variable_ptr_ptr) {
-               temp_variable *T = &T(op1->u.var);
+       if (Z_TYPE_P(T->str_offset.str) == IS_STRING) {
+               zval tmp;
+               zval *final_value = value;
 
-               if (Z_TYPE_P(T->str_offset.str) == IS_STRING)
-               do {
-                       zval tmp;
-                       zval *final_value = value;
+               if (((int)T->str_offset.offset < 0)) {
+                       zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
+                       return;
+               }
+               if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
+                       zend_uint i;
 
-                       if (((int)T->str_offset.offset < 0)) {
-                               zend_error(E_WARNING, "Illegal string offset:  %d", T->str_offset.offset);
-                               break;
+                       if (Z_STRLEN_P(T->str_offset.str)==0) {
+                               STR_FREE(Z_STRVAL_P(T->str_offset.str));
+                               Z_STRVAL_P(T->str_offset.str) = (char *) emalloc(T->str_offset.offset+1+1);
+                       } else {
+                               Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
                        }
-                       if (T->str_offset.offset >= Z_STRLEN_P(T->str_offset.str)) {
-                               zend_uint i;
-
-                               if (Z_STRLEN_P(T->str_offset.str)==0) {
-                                       STR_FREE(Z_STRVAL_P(T->str_offset.str));
-                                       Z_STRVAL_P(T->str_offset.str) = (char *) emalloc(T->str_offset.offset+1+1);
-                               } else {
-                                       Z_STRVAL_P(T->str_offset.str) = (char *) erealloc(Z_STRVAL_P(T->str_offset.str), T->str_offset.offset+1+1);
-                               }
-                               for (i=Z_STRLEN_P(T->str_offset.str); i<T->str_offset.offset; i++) {
-                                       Z_STRVAL_P(T->str_offset.str)[i] = ' ';
-                               }
-                               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;
+                       for (i=Z_STRLEN_P(T->str_offset.str); i<T->str_offset.offset; i++) {
+                               Z_STRVAL_P(T->str_offset.str)[i] = ' ';
                        }
+                       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;
+               }
 
-                       if (Z_TYPE_P(value)!=IS_STRING) {
-                               tmp = *value;
-                               if (op2->op_type & (IS_VAR|IS_CV)) {
-                                       zval_copy_ctor(&tmp);
-                               }
-                               convert_to_string(&tmp);
-                               final_value = &tmp;
+               if (Z_TYPE_P(value)!=IS_STRING) {
+                       tmp = *value;
+                       if (value_type & (IS_VAR|IS_CV)) {
+                               zval_copy_ctor(&tmp);
                        }
+                       convert_to_string(&tmp);
+                       final_value = &tmp;
+               }
 
-                       Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(final_value)[0];
+               Z_STRVAL_P(T->str_offset.str)[T->str_offset.offset] = Z_STRVAL_P(final_value)[0];
 
-                       if (op2->op_type == IS_TMP_VAR) {
-                               if (final_value == &T(op2->u.var).tmp_var) {
-                                       /* we can safely free final_value here
-                                        * because separation is done only
-                                        * in case op2->op_type == IS_VAR */
-                                       STR_FREE(Z_STRVAL_P(final_value));
-                               }
-                       }
-                       if (final_value == &tmp) {
-                               zval_dtor(final_value);
-                       }
-                       /*
-                        * the value of an assignment to a string offset is undefined
-                       T(result->u.var).var = &T->str_offset.str;
-                       */
-               } while (0);
-               /* zval_ptr_dtor(&T->str_offset.str); Nuke this line if it doesn't cause a leak */
-
-/*             T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr); */
-               if (!RETURN_VALUE_UNUSED(result)) {
-                       T(result->u.var).var.ptr_ptr = &value;
-                       PZVAL_LOCK(*T(result->u.var).var.ptr_ptr);
-                       AI_USE_PTR(T(result->u.var).var);
+               if (final_value == &tmp) {
+                       zval_dtor(final_value);
+               } else if (value_type == IS_TMP_VAR) {
+                       /* we can safely free final_value here
+                        * because separation is done only
+                        * in case value_type == IS_VAR */
+                       STR_FREE(Z_STRVAL_P(final_value));
                }
-               FREE_OP_VAR_PTR(free_op1);
-               return;
+               /*
+                * the value of an assignment to a string offset is undefined
+               T(result->u.var).var = &T->str_offset.str;
+               */
        }
+}
 
-       variable_ptr = *variable_ptr_ptr;
+static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value, int is_tmp_var TSRMLS_DC)
+{
+       zval *variable_ptr = *variable_ptr_ptr;
 
        if (variable_ptr == EG(error_zval_ptr)) {
-               if (result && !RETURN_VALUE_UNUSED(result)) {
-                       T(result->u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*T(result->u.var).var.ptr_ptr);
-                       AI_USE_PTR(T(result->u.var).var);
-               }
-               if (type==IS_TMP_VAR) {
+               if (is_tmp_var) {
                        zval_dtor(value);
                }
-               FREE_OP_VAR_PTR(free_op1);
-               return;
+               return EG(uninitialized_zval_ptr);
        }
 
        if (Z_TYPE_P(variable_ptr) == IS_OBJECT && Z_OBJ_HANDLER_P(variable_ptr, set)) {
                Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr_ptr, value TSRMLS_CC);
-               goto done_setting_var;
+               return value;
        }
 
        if (EG(ze1_compatibility_mode) && Z_TYPE_P(value) == IS_OBJECT) {
@@ -747,7 +718,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
                                zend_uint refcount = Z_REFCOUNT_P(variable_ptr);
                                zval garbage;
  
-                               if (type != IS_TMP_VAR) {
+                               if (!is_tmp_var) {
                                        Z_ADDREF_P(value);
                                }
                                garbage = *variable_ptr;
@@ -756,7 +727,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
                                Z_SET_ISREF_P(variable_ptr);
                                zend_error(E_STRICT, "Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'", class_name);
                                variable_ptr->value.obj = Z_OBJ_HANDLER_P(value, clone_obj)(value TSRMLS_CC);
-                               if (type != IS_TMP_VAR) {
+                               if (!is_tmp_var) {
                                        Z_DELREF_P(value);
                                }
                                zendi_zval_dtor(garbage);
@@ -786,86 +757,65 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
                        zend_uint refcount = Z_REFCOUNT_P(variable_ptr);
                        zval garbage;
 
-                       if (type!=IS_TMP_VAR) {
+                       if (!is_tmp_var) {
                                Z_ADDREF_P(value);
                        }
                        garbage = *variable_ptr;
                        *variable_ptr = *value;
                        Z_SET_REFCOUNT_P(variable_ptr, refcount);
                        Z_SET_ISREF_P(variable_ptr);
-                       if (type!=IS_TMP_VAR) {
+                       if (!is_tmp_var) {
                                zendi_zval_copy_ctor(*variable_ptr);
                                Z_DELREF_P(value);
                        }
                        zendi_zval_dtor(garbage);
                }
        } else {
-               Z_DELREF_P(variable_ptr);
-               if (Z_REFCOUNT_P(variable_ptr)==0) {
-                       switch (type) {
-                               case IS_CV:
-                               case IS_VAR:
-                                       /* break missing intentionally */
-                               case IS_CONST:
-                                       if (variable_ptr==value) {
-                                               Z_ADDREF_P(variable_ptr);
-                                       } else if (PZVAL_IS_REF(value)) {
-                                               zval tmp;
-
-                                               tmp = *value;
-                                               zval_copy_ctor(&tmp);
-                                               Z_SET_REFCOUNT(tmp, 1);
-                                               zendi_zval_dtor(*variable_ptr);
-                                               *variable_ptr = tmp;
-                                       } else {
-                                               Z_ADDREF_P(value);
-                                               zendi_zval_dtor(*variable_ptr);
-                                               safe_free_zval_ptr(variable_ptr);
-                                               *variable_ptr_ptr = value;
-                                       }
-                                       break;
-                               case IS_TMP_VAR:
+               if (Z_DELREF_P(variable_ptr)==0) {
+                       if (!is_tmp_var) {
+                               if (variable_ptr==value) {
+                                       Z_ADDREF_P(variable_ptr);
+                               } else if (PZVAL_IS_REF(value)) {
+                                       zval tmp;
+
+                                       tmp = *value;
+                                       zval_copy_ctor(&tmp);
+                                       Z_SET_REFCOUNT(tmp, 1);
                                        zendi_zval_dtor(*variable_ptr);
-                                       Z_SET_REFCOUNT_P(value, 1);
-                                       *variable_ptr = *value;
-                                       break;
-                                       EMPTY_SWITCH_DEFAULT_CASE()
-                                               }
+                                       *variable_ptr = tmp;
+                               } else {
+                                       Z_ADDREF_P(value);
+                                       zendi_zval_dtor(*variable_ptr);
+                                       safe_free_zval_ptr(variable_ptr);
+                                       *variable_ptr_ptr = value;
+                               }
+                       } else {
+                               zendi_zval_dtor(*variable_ptr);
+                               Z_SET_REFCOUNT_P(value, 1);
+                               *variable_ptr = *value;
+                       }
                } else { /* we need to split */
-                       switch (type) {
-                               case IS_CV:
-                               case IS_VAR:
-                                       /* break missing intentionally */
-                               case IS_CONST:
-                                       if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
-                                               ALLOC_ZVAL(variable_ptr);
-                                               *variable_ptr_ptr = variable_ptr;
-                                               *variable_ptr = *value;
-                                               zval_copy_ctor(variable_ptr);
-                                               Z_SET_REFCOUNT_P(variable_ptr, 1);
-                                               break;
-                                       }
+                       if (!is_tmp_var) {
+                               if (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0) {
+                                       ALLOC_ZVAL(variable_ptr);
+                                       *variable_ptr_ptr = variable_ptr;
+                                       *variable_ptr = *value;
+                                       zval_copy_ctor(variable_ptr);
+                                       Z_SET_REFCOUNT_P(variable_ptr, 1);
+                               } else {
                                        *variable_ptr_ptr = value;
                                        Z_ADDREF_P(value);
-                                       break;
-                               case IS_TMP_VAR:
-                                       ALLOC_ZVAL(*variable_ptr_ptr);
-                                       Z_SET_REFCOUNT_P(value, 1);
-                                       **variable_ptr_ptr = *value;
-                                       break;
-                                       EMPTY_SWITCH_DEFAULT_CASE()
-                                               }
+                               }
+                       } else {
+                               ALLOC_ZVAL(*variable_ptr_ptr);
+                               Z_SET_REFCOUNT_P(value, 1);
+                               **variable_ptr_ptr = *value;
+                       }
                }
                Z_UNSET_ISREF_PP(variable_ptr_ptr);
        }
 
-done_setting_var:
-       if (result && !RETURN_VALUE_UNUSED(result)) {
-               T(result->u.var).var.ptr_ptr = variable_ptr_ptr;
-               PZVAL_LOCK(*variable_ptr_ptr);
-               AI_USE_PTR(T(result->u.var).var);
-       }
-       FREE_OP_VAR_PTR(free_op1);
+       return *variable_ptr_ptr;
 }
 
 
@@ -1055,7 +1005,7 @@ static void zend_fetch_dimension_address(temp_variable *result, zval **container
        switch (Z_TYPE_P(container)) {
 
                case IS_ARRAY:
-                       if ((type==BP_VAR_W || type==BP_VAR_RW) && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) {
+                       if (type != BP_VAR_UNSET && Z_REFCOUNT_P(container)>1 && !PZVAL_IS_REF(container)) {
                                SEPARATE_ZVAL(container_ptr);
                                container = *container_ptr;
                        }
@@ -1075,9 +1025,6 @@ fetch_from_array:
                        if (result) {
                                result->var.ptr_ptr = retval;
                                PZVAL_LOCK(*retval);
-                               if (type == BP_VAR_R || type == BP_VAR_IS) {
-                                       AI_USE_PTR(result->var);
-                               }
                        }
                        return;
                        break;
@@ -1087,11 +1034,8 @@ fetch_from_array:
                                if (result) {
                                        result->var.ptr_ptr = &EG(error_zval_ptr);
                                        PZVAL_LOCK(EG(error_zval_ptr));
-                                       if (type == BP_VAR_R || type == BP_VAR_IS) {
-                                               AI_USE_PTR(result->var);
-                                       }
                                }
-                       } else if (type == BP_VAR_RW || type == BP_VAR_W) {
+                       } else if (type != BP_VAR_UNSET) {
 convert_to_array:
                                if (!PZVAL_IS_REF(container)) {
                                        SEPARATE_ZVAL(container_ptr);
@@ -1101,12 +1045,9 @@ convert_to_array:
                                array_init(container);
                                goto fetch_from_array;
                        } else if (result) {
-                       /* for read-mode only */                        
+                               /* for read-mode only */                        
                                result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
                                PZVAL_LOCK(EG(uninitialized_zval_ptr));
-                               if (type == BP_VAR_R || type == BP_VAR_IS) {
-                                       AI_USE_PTR(result->var);
-                               }
                        }
                        return;
                        break;
@@ -1114,7 +1055,7 @@ convert_to_array:
                case IS_STRING: {
                                zval tmp;
 
-                               if ((type == BP_VAR_RW || type == BP_VAR_W)  && Z_STRLEN_P(container)==0) {
+                               if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
                                        goto convert_to_array;
                                }
                                if (dim == NULL) {
@@ -1140,15 +1081,8 @@ convert_to_array:
                                        convert_to_long(&tmp);
                                        dim = &tmp;
                                }
-                               switch (type) {
-                                       case BP_VAR_R:
-                                       case BP_VAR_IS:
-                                       case BP_VAR_UNSET:
-                                               /* do nothing... */
-                                               break;
-                                       default:
-                                               SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
-                                               break;
+                               if (type != BP_VAR_UNSET) {
+                                       SEPARATE_ZVAL_IF_NOT_REF(container_ptr);
                                }
                                if (result) {
                                        container = *container_ptr;
@@ -1156,9 +1090,7 @@ convert_to_array:
                                        PZVAL_LOCK(container);
                                        result->str_offset.offset = Z_LVAL_P(dim);
                                        result->var.ptr_ptr = NULL;
-                                       if (type == BP_VAR_R || type == BP_VAR_IS) {
-                                               AI_USE_PTR(result->var);
-                                       }
+                                       result->var.ptr = NULL;
                                }
                                return;
                        }
@@ -1178,8 +1110,7 @@ convert_to_array:
                                overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
 
                                if (overloaded_result) {
-                                       if (!Z_ISREF_P(overloaded_result) &&
-                                           (type == BP_VAR_W || type == BP_VAR_RW  || type == BP_VAR_UNSET)) {
+                                       if (!Z_ISREF_P(overloaded_result)) {
                                                if (Z_REFCOUNT_P(overloaded_result) > 0) {
                                                        zval *tmp = overloaded_result;
 
@@ -1199,9 +1130,8 @@ convert_to_array:
                                        retval = &EG(error_zval_ptr);
                                }
                                if (result) {
-                                       result->var.ptr_ptr = retval;
-                                       AI_USE_PTR(result->var);
-                                       PZVAL_LOCK(*result->var.ptr_ptr);
+                                       AI_SET_PTR(result->var, *retval);
+                                       PZVAL_LOCK(*retval);
                                } else if (Z_REFCOUNT_PP(retval) == 0) {
                                        /* Destroy unused result from offsetGet() magic method */
                                        Z_SET_REFCOUNT_PP(retval, 1);
@@ -1215,37 +1145,150 @@ convert_to_array:
                        break;
 
                case IS_BOOL:
-                       if ((type == BP_VAR_RW || type == BP_VAR_W)  && Z_LVAL_P(container)==0) {
+                       if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
                                goto convert_to_array;
                        }
                        /* break missing intentionally */
 
                default:
-                       switch (type) {
-                               case BP_VAR_UNSET:
-                                       zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
-                                       /* break missing intentionally */
-                               case BP_VAR_R:
-                               case BP_VAR_IS:
-                                       if (result) {
-                                               result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
-                                               AI_USE_PTR(result->var);
+                       if (type == BP_VAR_UNSET) {
+                               zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
+                               if (result) {
+                                       AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                               }
+                       } else {
+                               zend_error(E_WARNING, "Cannot use a scalar value as an array");
+                               if (result) {
+                                       result->var.ptr_ptr = &EG(error_zval_ptr);
+                                       PZVAL_LOCK(EG(error_zval_ptr));
+                               }
+                       }
+                       break;
+       }
+}
+
+static void zend_fetch_dimension_address_read(temp_variable *result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
+{
+       zval *container;
+       zval **retval;
+
+       if (!container_ptr) {
+               zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+       }
+
+       container = *container_ptr;
+       switch (Z_TYPE_P(container)) {
+
+               case IS_ARRAY:
+                       if (dim == NULL) {
+                               zval *new_zval = &EG(uninitialized_zval);
+
+                               Z_ADDREF_P(new_zval);
+                               if (zend_hash_next_index_insert(Z_ARRVAL_P(container), &new_zval, sizeof(zval *), (void **) &retval) == FAILURE) {
+                                       zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
+                                       retval = &EG(error_zval_ptr);
+                                       Z_DELREF_P(new_zval);
+                               }
+                       } else {
+                               retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, type TSRMLS_CC);
+                       }
+                       if (result) {
+                               AI_SET_PTR(result->var, *retval);
+                               PZVAL_LOCK(*retval);
+                       }
+                       return;
+                       break;
+
+               case IS_NULL:
+                       if (container == EG(error_zval_ptr)) {
+                               if (result) {
+                                       AI_SET_PTR(result->var, EG(error_zval_ptr));
+                                       PZVAL_LOCK(EG(error_zval_ptr));
+                               }
+                       } else if (result) {
+                               AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
+                       return;
+                       break;
+
+               case IS_STRING: {
+                               zval tmp;
+
+                               if (dim == NULL) {
+                                       zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
+                               }
+
+                               if (Z_TYPE_P(dim) != IS_LONG) {
+                                       switch(Z_TYPE_P(dim)) {
+                                               /* case IS_LONG: */
+                                               case IS_STRING:
+                                               case IS_DOUBLE:
+                                               case IS_NULL:
+                                               case IS_BOOL:
+                                                       /* do nothing */
+                                                       break;
+                                               default:
+                                                       zend_error(E_WARNING, "Illegal offset type");
+                                                       break;
                                        }
-                                       return;
-                                       break;
-                               case BP_VAR_W:
-                               case BP_VAR_RW:
-                                       zend_error(E_WARNING, "Cannot use a scalar value as an array");
-                                       /* break missing intentionally */
-                               default:
+
+                                       tmp = *dim;
+                                       zval_copy_ctor(&tmp);
+                                       convert_to_long(&tmp);
+                                       dim = &tmp;
+                               }
+                               if (result) {
+                                       result->str_offset.str = container;
+                                       PZVAL_LOCK(container);
+                                       result->str_offset.offset = Z_LVAL_P(dim);
+                                       result->var.ptr_ptr = NULL;
+                                       result->var.ptr = NULL;
+                               }
+                               return;
+                       }
+                       break;
+
+               case IS_OBJECT:
+                       if (!Z_OBJ_HT_P(container)->read_dimension) {
+                               zend_error_noreturn(E_ERROR, "Cannot use object as array");
+                       } else {
+                               zval *overloaded_result;
+
+                               if (dim_is_tmp_var) {
+                                       zval *orig = dim;
+                                       MAKE_REAL_ZVAL_PTR(dim);
+                                       ZVAL_NULL(orig);
+                               }
+                               overloaded_result = Z_OBJ_HT_P(container)->read_dimension(container, dim, type TSRMLS_CC);
+
+                               if (overloaded_result) {
                                        if (result) {
-                                               result->var.ptr_ptr = &EG(error_zval_ptr);
-                                               PZVAL_LOCK(EG(error_zval_ptr));
+                                               AI_SET_PTR(result->var, 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);
                                        }
-                                       return;
-                                       break;
+                               } else if (result) {
+                                       AI_SET_PTR(result->var, EG(error_zval_ptr));
+                                       PZVAL_LOCK(EG(error_zval_ptr));
+                               }
+                               if (dim_is_tmp_var) {
+                                       zval_ptr_dtor(&dim);
+                               }
                        }
+                       return;
+                       break;
+
+               default:
+                       if (result) {
+                               AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
+                               PZVAL_LOCK(EG(uninitialized_zval_ptr));
+                       }
+                       return;
                        break;
        }
 }
@@ -1264,39 +1307,32 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
        }
 
        container = *container_ptr;
-       if (container == EG(error_zval_ptr)) {
-               if (result) {
-                       result->var.ptr_ptr = &EG(error_zval_ptr);
-                       PZVAL_LOCK(*result->var.ptr_ptr);
-               }
-               return;
-       }
-       /* this should modify object only if it's empty */
-       if (Z_TYPE_P(container) == IS_NULL
-               || (Z_TYPE_P(container) == IS_BOOL && Z_LVAL_P(container)==0)
-               || (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)) {
-               switch (type) {
-                       case BP_VAR_RW:
-                       case BP_VAR_W:
-                               if (!PZVAL_IS_REF(container)) {
-                                       SEPARATE_ZVAL(container_ptr);
-                                       container = *container_ptr;
-                               }
-                               object_init(container);
-                               break;
+       if (Z_TYPE_P(container) != IS_OBJECT) {
+               if (container == EG(error_zval_ptr)) {
+                       if (result) {
+                               result->var.ptr_ptr = &EG(error_zval_ptr);
+                               PZVAL_LOCK(*result->var.ptr_ptr);
+                       }
+                       return;
                }
-       }
 
-       if (Z_TYPE_P(container) != IS_OBJECT) {
-               if (result) {
-                       if (type == BP_VAR_R || type == BP_VAR_IS) {
-                               result->var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       } else {
+               /* this should modify object only if it's empty */
+               if (type != BP_VAR_UNSET &&
+                   ((Z_TYPE_P(container) == IS_NULL ||
+                    (Z_TYPE_P(container) == IS_BOOL && Z_LVAL_P(container)==0) ||
+                    (Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
+                       if (!PZVAL_IS_REF(container)) {
+                               SEPARATE_ZVAL(container_ptr);
+                               container = *container_ptr;
+                       }
+                       object_init(container);
+               } else {
+                       if (result) {
                                result->var.ptr_ptr = &EG(error_zval_ptr);
+                               PZVAL_LOCK(EG(error_zval_ptr));
                        }
-                       PZVAL_LOCK(*result->var.ptr_ptr);
+                       return;
                }
-               return;
        }
 
        if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
@@ -1307,30 +1343,30 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
                        if (Z_OBJ_HT_P(container)->read_property &&
                                (ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC)) != NULL) {
                                if (result) {
-                                       result->var.ptr = ptr;
-                                       result->var.ptr_ptr = &result->var.ptr;
+                                       AI_SET_PTR(result->var, ptr);
+                                       PZVAL_LOCK(ptr);
                                }
                        } else {
                                zend_error(E_ERROR, "Cannot access undefined property for object with overloaded property access");
                        }
                } else if (result) {
                        result->var.ptr_ptr = ptr_ptr;
+                       PZVAL_LOCK(*ptr_ptr);
                }
        } else if (Z_OBJ_HT_P(container)->read_property) {
+               zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC);
+
                if (result) {
-                       result->var.ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type TSRMLS_CC);
-                       result->var.ptr_ptr = &result->var.ptr;
+                       AI_SET_PTR(result->var, ptr);
+                       PZVAL_LOCK(ptr);
                }
        } else {
                zend_error(E_WARNING, "This object doesn't support property references");
                if (result) {
                        result->var.ptr_ptr = &EG(error_zval_ptr);
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
        }
-
-       if (result) {
-               PZVAL_LOCK(*result->var.ptr_ptr);
-       }
 }
 
 static inline zend_brk_cont_element* zend_brk_cont(zval *nest_levels_zval, int array_offset, zend_op_array *op_array, temp_variable *Ts TSRMLS_DC)
@@ -1358,7 +1394,7 @@ static inline zend_brk_cont_element* zend_brk_cont(zval *nest_levels_zval, int a
 
                        switch (brk_opline->opcode) {
                                case ZEND_SWITCH_FREE:
-                                       zend_switch_free(brk_opline, Ts TSRMLS_CC);
+                                       zend_switch_free(&T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC);
                                        break;
                                case ZEND_FREE:
                                        zendi_zval_dtor(T(brk_opline->op1.u.var).tmp_var);
index 51f0efe3f8e4eecc54510c813da413472f4bce83..747e5a7b10323e890d1699d1b8bbe525009a75d5 100644 (file)
@@ -291,7 +291,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
        zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -304,8 +303,9 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -323,8 +323,9 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -366,15 +367,17 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -420,7 +423,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -438,9 +441,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                FREE_OP2();
                FREE_OP1_VAR_PTR();
@@ -465,9 +467,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        FREE_OP2();
 
@@ -729,9 +730,8 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
        }
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                FREE_OP1_VAR_PTR();
                ZEND_VM_NEXT_OPCODE();
@@ -752,9 +752,8 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        FREE_OP1_VAR_PTR();
@@ -772,9 +771,8 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
        }
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                FREE_OP1_VAR_PTR();
                ZEND_VM_NEXT_OPCODE();
@@ -795,9 +793,8 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        FREE_OP1_VAR_PTR();
@@ -984,16 +981,16 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type
                if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
                }
-               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
                        case BP_VAR_R:
                        case BP_VAR_IS:
-                               AI_USE_PTR(EX_T(opline->result.u.var).var);
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, *retval);
                                break;
                        case BP_VAR_UNSET: {
                                zend_free_op free_res;
 
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                                PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
                                if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
                                        SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
@@ -1001,6 +998,9 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type
                                PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
                                FREE_OP_VAR_PTR(free_res);
                                break;
+                       default:
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
+                               break;
                        }
                }
        }
@@ -1049,7 +1049,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
        FREE_OP2();
        FREE_OP1_VAR_PTR();
        ZEND_VM_NEXT_OPCODE();
@@ -1111,7 +1111,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV)
        zend_free_op free_op1, free_op2;
        zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC);
        FREE_OP2();
        FREE_OP1_VAR_PTR();
        ZEND_VM_NEXT_OPCODE();
@@ -1121,24 +1121,26 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
+       zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       if (OP2_TYPE == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC);
-       FREE_OP2();
-       if (OP1_TYPE == IS_VAR && type == BP_VAR_W && OP1_FREE &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
+               if (OP1_TYPE == IS_VAR && OP1_FREE &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
+               }
+       } else {
+               if (OP2_TYPE == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
        }
+       FREE_OP2();
        FREE_OP1_VAR_PTR();
        ZEND_VM_NEXT_OPCODE();
 }
@@ -1190,20 +1192,13 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
 ZEND_VM_HELPER_EX(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|TMP|VAR|CV, int type)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
        zend_free_op free_op1;
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = GET_OP1_OBJ_ZVAL_PTR(type);
+       zval *container = GET_OP1_OBJ_ZVAL_PTR(type);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
                FREE_OP1();
                ZEND_VM_NEXT_OPCODE();
@@ -1214,26 +1209,30 @@ ZEND_VM_HELPER_EX(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = GET_OP2_ZVAL_PTR(BP_VAR_R);
+               zval *retval;
 
                if (IS_OP2_TMP_FREE()) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (IS_OP2_TMP_FREE()) {
@@ -1409,18 +1408,17 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST)
 
        if (Z_TYPE_P(container) != IS_ARRAY) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                zend_free_op free_op2;
                zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-               EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
-               SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC));
+               SELECTIVE_PZVAL_LOCK(EX_T(opline->result.u.var).var.ptr, &opline->result);
                FREE_OP2();
        }
-       AI_USE_PTR(EX_T(opline->result.u.var).var);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -1428,10 +1426,19 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-       zend_free_op free_op1;
+       zend_free_op free_op1, free_op2;
        zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
+       zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (IS_OP2_TMP_FREE()) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (IS_OP2_TMP_FREE()) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               FREE_OP2();
+       }
        FREE_OP1_VAR_PTR();
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -1453,17 +1460,39 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               zend_free_op free_op2;
+               zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
+
+               if (IS_OP2_TMP_FREE()) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (IS_OP2_TMP_FREE()) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+                       FREE_OP2();
+               }
        } else {
-               zend_free_op free_op2, free_op_data1;
+               zend_free_op free_op2, free_op_data1, free_op_data2;
                zval *value;
                zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
                FREE_OP2();
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
        FREE_OP1_VAR_PTR();
@@ -1475,10 +1504,23 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
 ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
 {
        zend_op *opline = EX(opline);
-       zend_free_op free_op2;
+       zend_free_op free_op1, free_op2;
        zval *value = GET_OP2_ZVAL_PTR(BP_VAR_R);
+       zval **variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, OP2_TYPE TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, IS_OP2_TMP_FREE() TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
+
+       FREE_OP1_VAR_PTR();
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (IS_OP2_TMP_FREE()?IS_TMP_VAR:OP2_TYPE), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
        FREE_OP2_IF_VAR();
 
@@ -1511,9 +1553,8 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
        zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
                PZVAL_LOCK(*variable_ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        FREE_OP1_VAR_PTR();
@@ -2456,7 +2497,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
 ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
 {
        zend_op *opline = EX(opline);
-       zval **param, *assignment_value;
+       zval **param, *assignment_value, **var_ptr;
        zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
        zend_free_op free_res;
 
@@ -2480,10 +2521,11 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
                        assignment_value = &opline->op2.u.constant;
                }
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
-               zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
+               
+               var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
+               zend_assign_to_variable(var_ptr, assignment_value, 0 TSRMLS_CC);
        } else {
-               zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
-
+               var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
                assignment_value = *param;
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
                if (PZVAL_IS_REF(assignment_value)) {
@@ -2560,14 +2602,14 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
                 */
                FREE_OP1();
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
 
 ZEND_VM_HANDLER(49, ZEND_SWITCH_FREE, TMP|VAR, ANY)
 {
-       zend_switch_free(EX(opline), EX(Ts) TSRMLS_CC);
+       zend_switch_free(&EX_T(EX(opline)->op1.u.var), OP1_TYPE, EX(opline)->extended_value TSRMLS_CC);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -2595,16 +2637,16 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
 
        if (constructor == NULL) {
                if (RETURN_VALUE_USED(opline)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-                       EX_T(opline->result.u.var).var.ptr = object_zval;
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, object_zval);
                } else {
                        zval_ptr_dtor(&object_zval);
                }
                ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.u.opline_num);
        } else {
-               SELECTIVE_PZVAL_LOCK(object_zval, &opline->result);
-               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-               EX_T(opline->result.u.var).var.ptr = object_zval;
+               if (RETURN_VALUE_USED(opline)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, object_zval);
+                       PZVAL_LOCK(object_zval);
+               }
 
                zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline)));
 
@@ -3292,9 +3334,8 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
                }
        }
 
+       AI_SET_PTR(EX_T(opline->result.u.var).var, array_ptr);
        PZVAL_LOCK(array_ptr);
-       EX_T(opline->result.u.var).var.ptr = array_ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (iter) {
                iter->index = 0;
@@ -3478,9 +3519,8 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
                EX_T(opline->result.u.var).var.ptr_ptr = value;
                Z_ADDREF_PP(value);
        } else {
-               EX_T(opline->result.u.var).var.ptr_ptr = value;
-               PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *value);
+               PZVAL_LOCK(*value);
        }
 
        if (use_key) {
@@ -3948,7 +3988,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
 
                                switch (brk_opline->opcode) {
                                        case ZEND_SWITCH_FREE:
-                                               zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
+                                               zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC);
                                                break;
                                        case ZEND_FREE:
                                                zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
index 10a569f5a7853341fd53bd869116290dd075b41c..951ff462f207f2662e2749dcd253d2475690f4e6 100644 (file)
@@ -398,16 +398,16 @@ static int ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        if (constructor == NULL) {
                if (RETURN_VALUE_USED(opline)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-                       EX_T(opline->result.u.var).var.ptr = object_zval;
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, object_zval);
                } else {
                        zval_ptr_dtor(&object_zval);
                }
                ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.u.opline_num);
        } else {
-               SELECTIVE_PZVAL_LOCK(object_zval, &opline->result);
-               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-               EX_T(opline->result.u.var).var.ptr = object_zval;
+               if (RETURN_VALUE_USED(opline)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, object_zval);
+                       PZVAL_LOCK(object_zval);
+               }
 
                zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline)));
 
@@ -566,7 +566,7 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
                                switch (brk_opline->opcode) {
                                        case ZEND_SWITCH_FREE:
-                                               zend_switch_free(brk_opline, EX(Ts) TSRMLS_CC);
+                                               zend_switch_free(&EX_T(brk_opline->op1.u.var), brk_opline->op1.op_type, brk_opline->extended_value TSRMLS_CC);
                                                break;
                                        case ZEND_FREE:
                                                zendi_zval_dtor(EX_T(brk_opline->op1.u.var).tmp_var);
@@ -715,7 +715,7 @@ static int ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval **param, *assignment_value;
+       zval **param, *assignment_value, **var_ptr;
        zend_uint arg_num = Z_LVAL(opline->op1.u.constant);
        zend_free_op free_res;
 
@@ -739,10 +739,11 @@ static int ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        assignment_value = &opline->op2.u.constant;
                }
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
-               zend_assign_to_variable(NULL, &opline->result, NULL, assignment_value, IS_VAR, EX(Ts) TSRMLS_CC);
-       } else {
-               zval **var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
 
+               var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
+               zend_assign_to_variable(var_ptr, assignment_value, 0 TSRMLS_CC);
+       } else {
+               var_ptr = get_zval_ptr_ptr(&opline->result, EX(Ts), &free_res, BP_VAR_W);
                assignment_value = *param;
                zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
                if (PZVAL_IS_REF(assignment_value)) {
@@ -1235,16 +1236,16 @@ static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLE
                if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
                }
-               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
                        case BP_VAR_R:
                        case BP_VAR_IS:
-                               AI_USE_PTR(EX_T(opline->result.u.var).var);
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, *retval);
                                break;
                        case BP_VAR_UNSET: {
                                zend_free_op free_res;
 
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                                PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
                                if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
                                        SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
@@ -1252,6 +1253,9 @@ static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLE
                                PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
                                FREE_OP_VAR_PTR(free_res);
                                break;
+                       default:
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
+                               break;
                        }
                }
        }
@@ -1919,9 +1923,8 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
        }
 
+       AI_SET_PTR(EX_T(opline->result.u.var).var, array_ptr);
        PZVAL_LOCK(array_ptr);
-       EX_T(opline->result.u.var).var.ptr = array_ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (iter) {
                iter->index = 0;
@@ -2351,18 +2354,17 @@ static int ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
 
        if (Z_TYPE_P(container) != IS_ARRAY) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
 
                zval *dim = &opline->op2.u.constant;
 
-               EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
-               SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC));
+               SELECTIVE_PZVAL_LOCK(EX_T(opline->result.u.var).var.ptr, &opline->result);
 
        }
-       AI_USE_PTR(EX_T(opline->result.u.var).var);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -2481,7 +2483,7 @@ static int ZEND_CASE_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -3035,7 +3037,7 @@ static int ZEND_CASE_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -3483,7 +3485,7 @@ static int ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -4112,7 +4114,7 @@ static int ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -4336,16 +4338,16 @@ static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_
                if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
                }
-               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
                        case BP_VAR_R:
                        case BP_VAR_IS:
-                               AI_USE_PTR(EX_T(opline->result.u.var).var);
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, *retval);
                                break;
                        case BP_VAR_UNSET: {
                                zend_free_op free_res;
 
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                                PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
                                if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
                                        SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
@@ -4353,6 +4355,9 @@ static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_
                                PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
                                FREE_OP_VAR_PTR(free_res);
                                break;
+                       default:
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
+                               break;
                        }
                }
        }
@@ -4634,7 +4639,7 @@ static int ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
 static int ZEND_SWITCH_FREE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       zend_switch_free(EX(opline), EX(Ts) TSRMLS_CC);
+       zend_switch_free(&EX_T(EX(opline)->op1.u.var), IS_TMP_VAR, EX(opline)->extended_value TSRMLS_CC);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5022,9 +5027,8 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
        }
 
+       AI_SET_PTR(EX_T(opline->result.u.var).var, array_ptr);
        PZVAL_LOCK(array_ptr);
-       EX_T(opline->result.u.var).var.ptr = array_ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (iter) {
                iter->index = 0;
@@ -5478,18 +5482,17 @@ static int ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 
        if (Z_TYPE_P(container) != IS_ARRAY) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
 
                zval *dim = &opline->op2.u.constant;
 
-               EX_T(opline->result.u.var).var.ptr_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC);
-               SELECTIVE_PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &opline->result);
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, BP_VAR_R TSRMLS_CC));
+               SELECTIVE_PZVAL_LOCK(EX_T(opline->result.u.var).var.ptr, &opline->result);
 
        }
-       AI_USE_PTR(EX_T(opline->result.u.var).var);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5598,7 +5601,7 @@ static int ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                zval_dtor(free_op1.var);
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -6045,7 +6048,7 @@ static int ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                zval_dtor(free_op1.var);
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -6492,7 +6495,7 @@ static int ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                zval_dtor(free_op1.var);
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -7029,7 +7032,7 @@ static int ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                zval_dtor(free_op1.var);
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -7160,9 +7163,8 @@ static int ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                ZEND_VM_NEXT_OPCODE();
@@ -7183,9 +7185,8 @@ static int ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -7203,9 +7204,8 @@ static int ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                ZEND_VM_NEXT_OPCODE();
@@ -7226,9 +7226,8 @@ static int ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -7415,16 +7414,16 @@ static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_
                if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
                }
-               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
                        case BP_VAR_R:
                        case BP_VAR_IS:
-                               AI_USE_PTR(EX_T(opline->result.u.var).var);
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, *retval);
                                break;
                        case BP_VAR_UNSET: {
                                zend_free_op free_res;
 
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                                PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
                                if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
                                        SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
@@ -7432,6 +7431,9 @@ static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_
                                PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
                                FREE_OP_VAR_PTR(free_res);
                                break;
+                       default:
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
+                               break;
                        }
                }
        }
@@ -7812,7 +7814,7 @@ static int ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
 static int ZEND_SWITCH_FREE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       zend_switch_free(EX(opline), EX(Ts) TSRMLS_CC);
+       zend_switch_free(&EX_T(EX(opline)->op1.u.var), IS_VAR, EX(opline)->extended_value TSRMLS_CC);
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -8200,9 +8202,8 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
        }
 
+       AI_SET_PTR(EX_T(opline->result.u.var).var, array_ptr);
        PZVAL_LOCK(array_ptr);
-       EX_T(opline->result.u.var).var.ptr = array_ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (iter) {
                iter->index = 0;
@@ -8386,9 +8387,8 @@ static int ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                EX_T(opline->result.u.var).var.ptr_ptr = value;
                Z_ADDREF_PP(value);
        } else {
-               EX_T(opline->result.u.var).var.ptr_ptr = value;
-               PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *value);
+               PZVAL_LOCK(*value);
        }
 
        if (use_key) {
@@ -8787,7 +8787,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*binary_op)(zval
        zval *property = &opline->op2.u.constant;
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -8800,8 +8799,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*binary_op)(zval
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -8819,8 +8819,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*binary_op)(zval
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -8862,15 +8863,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*binary_op)(zval
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -8916,7 +8919,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binary_op)(zval *re
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -8934,9 +8937,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binary_op)(zval *re
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -8961,9 +8963,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binary_op)(zval *re
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -9224,7 +9225,7 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -9286,7 +9287,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *dim = &opline->op2.u.constant;
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -9296,24 +9297,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
-
-       if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = &opline->op2.u.constant;
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
+       zval *dim = &opline->op2.u.constant;
 
-       if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
                }
+       } else {
+               if (IS_CONST == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+               }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
+
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
 }
@@ -9365,20 +9368,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_VAR_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
        zend_free_op free_op1;
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                ZEND_VM_NEXT_OPCODE();
@@ -9389,26 +9385,30 @@ static int zend_fetch_property_address_read_helper_SPEC_VAR_CONST(int type, ZEND
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
 
                zval *offset  = &opline->op2.u.constant;
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -9582,8 +9582,17 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *op_data = opline+1;
        zend_free_op free_op1;
        zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *property_name = &opline->op2.u.constant;
+
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -9605,16 +9614,38 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+
+               zval *property_name = &opline->op2.u.constant;
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+
+               }
        } else {
-               zend_free_op free_op_data1;
+               zend_free_op free_op_data1, free_op_data2;
                zval *value;
                zval *dim = &opline->op2.u.constant;
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -9626,10 +9657,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-
+       zend_free_op free_op1;
        zval *value = &opline->op2.u.constant;
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
+
+       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CONST), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        ZEND_VM_NEXT_OPCODE();
@@ -9806,7 +9850,7 @@ static int ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -10482,7 +10526,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *
        zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -10495,8 +10538,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -10514,8 +10558,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -10557,15 +10602,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*binary_op)(zval *
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -10611,7 +10658,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_op)(zval *resu
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -10629,9 +10676,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_op)(zval *resu
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                zval_dtor(free_op2.var);
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -10656,9 +10702,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_op)(zval *resu
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        zval_dtor(free_op2.var);
 
@@ -10920,7 +10965,7 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -10982,7 +11027,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -10992,24 +11037,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
+       zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, type TSRMLS_CC);
-       zval_dtor(free_op2.var);
-       if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC);
+               if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
+               }
+       } else {
+               if (IS_TMP_VAR == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
        }
+       zval_dtor(free_op2.var);
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
 }
@@ -11061,20 +11108,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_VAR_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
        zend_free_op free_op1;
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                ZEND_VM_NEXT_OPCODE();
@@ -11085,26 +11125,30 @@ static int zend_fetch_property_address_read_helper_SPEC_VAR_TMP(int type, ZEND_O
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval *retval;
 
                if (1) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (1) {
@@ -11276,10 +11320,19 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-       zend_free_op free_op1;
+       zend_free_op free_op1, free_op2;
        zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (1) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (1) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               zval_dtor(free_op2.var);
+       }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -11301,17 +11354,39 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               zend_free_op free_op2;
+               zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+
+               if (1) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (1) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+                       zval_dtor(free_op2.var);
+               }
        } else {
-               zend_free_op free_op2, free_op_data1;
+               zend_free_op free_op2, free_op_data1, free_op_data2;
                zval *value;
                zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -11323,10 +11398,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zend_free_op free_op2;
+       zend_free_op free_op1, free_op2;
        zval *value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 1 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
+
+       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (1?IS_TMP_VAR:IS_TMP_VAR), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        ZEND_VM_NEXT_OPCODE();
@@ -11505,7 +11593,7 @@ static int ZEND_CASE_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -12109,7 +12197,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*binary_op)(zval *
        zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -12122,8 +12209,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*binary_op)(zval *
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -12141,8 +12229,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*binary_op)(zval *
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -12184,15 +12273,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*binary_op)(zval *
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -12238,7 +12329,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_op)(zval *resu
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -12256,9 +12347,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_op)(zval *resu
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12283,9 +12373,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_op)(zval *resu
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -12547,7 +12636,7 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -12609,7 +12698,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1, free_op2;
        zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -12619,24 +12708,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
+       zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
-       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
-       if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
                }
+       } else {
+               if (IS_VAR == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+               }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
+       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
 }
@@ -12688,20 +12779,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_VAR_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
        zend_free_op free_op1;
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                ZEND_VM_NEXT_OPCODE();
@@ -12712,26 +12796,30 @@ static int zend_fetch_property_address_read_helper_SPEC_VAR_VAR(int type, ZEND_O
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -12903,10 +12991,19 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-       zend_free_op free_op1;
+       zend_free_op free_op1, free_op2;
        zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+       }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -12928,17 +13025,39 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               zend_free_op free_op2;
+               zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+                       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+               }
        } else {
-               zend_free_op free_op2, free_op_data1;
+               zend_free_op free_op2, free_op_data1, free_op_data2;
                zval *value;
                zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12950,10 +13069,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zend_free_op free_op2;
+       zend_free_op free_op1, free_op2;
        zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
+
+       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_VAR), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -12986,9 +13118,8 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
                PZVAL_LOCK(*variable_ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13170,7 +13301,7 @@ static int ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -13540,7 +13671,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zva
        zval *property = NULL;
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -13553,8 +13683,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zva
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -13572,8 +13703,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zva
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -13615,15 +13747,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zva
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -13669,7 +13803,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *r
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -13687,9 +13821,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *r
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13714,9 +13847,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *r
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -13837,24 +13969,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_A
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
-
-       if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = NULL;
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
+       zval *dim = NULL;
 
-       if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
                }
+       } else {
+               if (IS_UNUSED == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+               }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
+
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
 }
@@ -13874,17 +14008,39 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+
+               zval *property_name = NULL;
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+
+               }
        } else {
-               zend_free_op free_op_data1;
+               zend_free_op free_op_data1, free_op_data2;
                zval *value;
                zval *dim = NULL;
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
-               FREE_OP_IF_VAR(free_op_data1);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
+               FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        /* assign_dim has two opcodes! */
@@ -14318,7 +14474,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*binary_op)(zval *r
        zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -14331,8 +14486,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*binary_op)(zval *r
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -14350,8 +14506,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*binary_op)(zval *r
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -14393,15 +14550,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*binary_op)(zval *r
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -14447,7 +14606,7 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_op)(zval *resul
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -14465,9 +14624,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_op)(zval *resul
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -14492,9 +14650,8 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_op)(zval *resul
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -14755,7 +14912,7 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -14817,7 +14974,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op1;
        zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
@@ -14827,24 +14984,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
-
-       if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, type TSRMLS_CC);
+       zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       if (IS_VAR == IS_VAR && type == BP_VAR_W && (free_op1.var != NULL) &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_VAR == IS_VAR && (free_op1.var != NULL) &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
+               }
+       } else {
+               if (IS_CV == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
+
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        ZEND_VM_NEXT_OPCODE();
 }
@@ -14896,20 +15055,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_VAR_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
        zend_free_op free_op1;
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *container = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                ZEND_VM_NEXT_OPCODE();
@@ -14920,26 +15072,30 @@ static int zend_fetch_property_address_read_helper_SPEC_VAR_CV(int type, ZEND_OP
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
 
                zval *offset  = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -15113,8 +15269,17 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *op_data = opline+1;
        zend_free_op free_op1;
        zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+       zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
+
+       }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -15136,16 +15301,38 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+
+               zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+
+               }
        } else {
-               zend_free_op free_op_data1;
+               zend_free_op free_op_data1, free_op_data2;
                zval *value;
                zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -15157,10 +15344,23 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-
+       zend_free_op free_op1;
        zval *value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
+
+       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CV), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        ZEND_VM_NEXT_OPCODE();
@@ -15192,9 +15392,8 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
                PZVAL_LOCK(*variable_ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -15373,7 +15572,7 @@ static int ZEND_CASE_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
                if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -15825,7 +16024,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int (*binary_op)(z
        zval *property = &opline->op2.u.constant;
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -15838,8 +16036,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int (*binary_op)(z
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -15857,8 +16056,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int (*binary_op)(z
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -15900,15 +16100,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int (*binary_op)(z
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -15953,7 +16155,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -15971,9 +16173,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
 
@@ -15998,9 +16199,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -16253,20 +16453,13 @@ static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
 
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_obj_zval_ptr_unused(TSRMLS_C);
+       zval *container = _get_obj_zval_ptr_unused(TSRMLS_C);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -16277,26 +16470,30 @@ static int zend_fetch_property_address_read_helper_SPEC_UNUSED_CONST(int type, Z
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
 
                zval *offset  = &opline->op2.u.constant;
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -16467,8 +16664,17 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *op_data = opline+1;
 
        zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+       zval *property_name = &opline->op2.u.constant;
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
+
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -16884,7 +17090,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zva
        zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -16897,8 +17102,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zva
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -16916,8 +17122,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zva
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -16959,15 +17166,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zva
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -17012,7 +17221,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *r
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 1, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -17030,9 +17239,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *r
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                zval_dtor(free_op2.var);
 
@@ -17057,9 +17265,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *r
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        zval_dtor(free_op2.var);
 
@@ -17313,20 +17520,13 @@ static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
 
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_obj_zval_ptr_unused(TSRMLS_C);
+       zval *container = _get_obj_zval_ptr_unused(TSRMLS_C);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -17337,26 +17537,30 @@ static int zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP(int type, ZEN
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval *retval;
 
                if (1) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (1) {
@@ -17525,10 +17729,19 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-
+       zend_free_op free_op2;
        zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+       zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (1) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (1) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               zval_dtor(free_op2.var);
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -17873,7 +18086,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zva
        zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -17886,8 +18098,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zva
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -17905,8 +18118,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zva
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -17948,15 +18162,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zva
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -18001,7 +18217,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *r
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -18019,9 +18235,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *r
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -18046,9 +18261,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *r
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -18302,20 +18516,13 @@ static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
-
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
 
-       container = _get_obj_zval_ptr_unused(TSRMLS_C);
+       zval *container = _get_obj_zval_ptr_unused(TSRMLS_C);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -18326,26 +18533,30 @@ static int zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR(int type, ZEN
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -18514,10 +18725,19 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-
+       zend_free_op free_op2;
        zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+       zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -18862,7 +19082,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(
        zval *property = NULL;
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -18875,8 +19094,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -18894,8 +19114,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -18937,15 +19158,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -18990,7 +19213,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -19008,9 +19231,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
 
@@ -19035,9 +19257,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -19128,7 +19349,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval
        zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -19141,8 +19361,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -19160,8 +19381,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -19203,15 +19425,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -19256,7 +19480,7 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *re
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -19274,9 +19498,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *re
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
 
@@ -19301,9 +19524,8 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *re
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -19556,20 +19778,13 @@ static int ZEND_POST_DEC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
 
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_obj_zval_ptr_unused(TSRMLS_C);
+       zval *container = _get_obj_zval_ptr_unused(TSRMLS_C);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -19580,26 +19795,30 @@ static int zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(int type, ZEND
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
 
                zval *offset  = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -19770,8 +19989,17 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *op_data = opline+1;
 
        zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+       zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
+
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -20138,9 +20366,8 @@ static int ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -20161,9 +20388,8 @@ static int ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        ZEND_VM_NEXT_OPCODE();
@@ -20180,9 +20406,8 @@ static int ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -20203,9 +20428,8 @@ static int ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        ZEND_VM_NEXT_OPCODE();
@@ -20388,16 +20612,16 @@ static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_A
                if (opline->extended_value & ZEND_FETCH_MAKE_REF) {
                        SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
                }
-               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                PZVAL_LOCK(*retval);
                switch (type) {
                        case BP_VAR_R:
                        case BP_VAR_IS:
-                               AI_USE_PTR(EX_T(opline->result.u.var).var);
+                               AI_SET_PTR(EX_T(opline->result.u.var).var, *retval);
                                break;
                        case BP_VAR_UNSET: {
                                zend_free_op free_res;
 
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
                                PZVAL_UNLOCK(*EX_T(opline->result.u.var).var.ptr_ptr, &free_res);
                                if (EX_T(opline->result.u.var).var.ptr_ptr != &EG(uninitialized_zval_ptr)) {
                                        SEPARATE_ZVAL_IF_NOT_REF(EX_T(opline->result.u.var).var.ptr_ptr);
@@ -20405,6 +20629,9 @@ static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_A
                                PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
                                FREE_OP_VAR_PTR(free_res);
                                break;
+                       default:
+                               EX_T(opline->result.u.var).var.ptr_ptr = retval;
+                               break;
                        }
                }
        }
@@ -21160,9 +21387,8 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                }
        }
 
+       AI_SET_PTR(EX_T(opline->result.u.var).var, array_ptr);
        PZVAL_LOCK(array_ptr);
-       EX_T(opline->result.u.var).var.ptr = array_ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
 
        if (iter) {
                iter->index = 0;
@@ -21598,7 +21824,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*binary_op)(zval
        zval *property = &opline->op2.u.constant;
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -21611,8 +21836,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*binary_op)(zval
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -21630,8 +21856,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*binary_op)(zval
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -21673,15 +21900,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*binary_op)(zval
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -21726,7 +21955,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary_op)(zval *res
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -21744,9 +21973,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary_op)(zval *res
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
 
@@ -21771,9 +21999,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary_op)(zval *res
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -22034,7 +22261,7 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
 
 
        ZEND_VM_NEXT_OPCODE();
@@ -22095,7 +22322,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        zval *dim = &opline->op2.u.constant;
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
 
 
        ZEND_VM_NEXT_OPCODE();
@@ -22105,25 +22332,27 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
-
-       if (IS_CONST == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = &opline->op2.u.constant;
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
+       zval *dim = &opline->op2.u.constant;
 
-       if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_CV == IS_VAR && 0 &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
+               }
+       } else {
+               if (IS_CONST == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
 
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -22174,20 +22403,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_CV_CONST(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
-
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
 
-       container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
+       zval *container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -22198,26 +22420,30 @@ static int zend_fetch_property_address_read_helper_SPEC_CV_CONST(int type, ZEND_
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
 
                zval *offset  = &opline->op2.u.constant;
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -22388,8 +22614,17 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *op_data = opline+1;
 
        zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+       zval *property_name = &opline->op2.u.constant;
+
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -22411,16 +22646,38 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+
+               zval *property_name = &opline->op2.u.constant;
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+
+               }
        } else {
-               zend_free_op free_op_data1;
+               zend_free_op free_op_data1, free_op_data2;
                zval *value;
                zval *dim = &opline->op2.u.constant;
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -22434,8 +22691,19 @@ static int ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
 
        zval *value = &opline->op2.u.constant;
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CONST), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        ZEND_VM_NEXT_OPCODE();
@@ -22522,7 +22790,7 @@ static int ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -23122,7 +23390,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*binary_op)(zval *r
        zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -23135,8 +23402,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*binary_op)(zval *r
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -23154,8 +23422,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*binary_op)(zval *r
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -23197,15 +23466,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*binary_op)(zval *r
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -23250,7 +23521,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_op)(zval *resul
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -23268,9 +23539,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_op)(zval *resul
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                zval_dtor(free_op2.var);
 
@@ -23295,9 +23565,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_op)(zval *resul
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        zval_dtor(free_op2.var);
 
@@ -23559,7 +23828,7 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
        zval_dtor(free_op2.var);
 
        ZEND_VM_NEXT_OPCODE();
@@ -23620,7 +23889,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op2;
        zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC);
        zval_dtor(free_op2.var);
 
        ZEND_VM_NEXT_OPCODE();
@@ -23630,24 +23899,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
+       zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (IS_TMP_VAR == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 1, type TSRMLS_CC);
-       zval_dtor(free_op2.var);
-       if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC);
+               if (IS_CV == IS_VAR && 0 &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
+               }
+       } else {
+               if (IS_TMP_VAR == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC);
        }
+       zval_dtor(free_op2.var);
 
        ZEND_VM_NEXT_OPCODE();
 }
@@ -23699,20 +23970,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_CV_TMP(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
-
 
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
+       zval *container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -23723,26 +23987,30 @@ static int zend_fetch_property_address_read_helper_SPEC_CV_TMP(int type, ZEND_OP
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval *retval;
 
                if (1) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (1) {
@@ -23911,10 +24179,19 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-
+       zend_free_op free_op2;
        zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+       zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (1) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (1) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               zval_dtor(free_op2.var);
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -23936,17 +24213,39 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               zend_free_op free_op2;
+               zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+
+               if (1) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (1) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+                       zval_dtor(free_op2.var);
+               }
        } else {
-               zend_free_op free_op2, free_op_data1;
+               zend_free_op free_op2, free_op_data1, free_op_data2;
                zval *value;
                zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -23960,8 +24259,19 @@ static int ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        zend_free_op free_op2;
        zval *value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 1 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (1?IS_TMP_VAR:IS_TMP_VAR), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        ZEND_VM_NEXT_OPCODE();
@@ -24050,7 +24360,7 @@ static int ZEND_CASE_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -24650,7 +24960,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*binary_op)(zval *r
        zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -24663,8 +24972,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*binary_op)(zval *r
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -24682,8 +24992,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*binary_op)(zval *r
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -24725,15 +25036,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*binary_op)(zval *r
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -24778,7 +25091,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_op)(zval *resul
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -24796,9 +25109,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_op)(zval *resul
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -24823,9 +25135,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_op)(zval *resul
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -25087,7 +25398,7 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
        ZEND_VM_NEXT_OPCODE();
@@ -25148,7 +25459,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_free_op free_op2;
        zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
        ZEND_VM_NEXT_OPCODE();
@@ -25158,24 +25469,26 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1, free_op2;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
+       zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       if (IS_VAR == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
-       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
-       if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_CV == IS_VAR && 0 &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
                }
+       } else {
+               if (IS_VAR == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+               }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
+       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
        ZEND_VM_NEXT_OPCODE();
 }
@@ -25227,20 +25540,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_CV_VAR(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
 
-
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
+       zval *container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -25251,26 +25557,30 @@ static int zend_fetch_property_address_read_helper_SPEC_CV_VAR(int type, ZEND_OP
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
                zend_free_op free_op2;
                zval *offset  = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -25439,10 +25749,19 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_op *op_data = opline+1;
-
+       zend_free_op free_op2;
        zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+       zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
+               if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -25464,17 +25783,39 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               zend_free_op free_op2;
+               zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+                       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+               }
        } else {
-               zend_free_op free_op2, free_op_data1;
+               zend_free_op free_op2, free_op_data1, free_op_data2;
                zval *value;
                zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
                if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -25488,8 +25829,19 @@ static int ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
        zend_free_op free_op2;
        zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_VAR), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
 
@@ -25522,9 +25874,8 @@ static int ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
                PZVAL_LOCK(*variable_ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -25615,7 +25966,7 @@ static int ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }
@@ -25981,7 +26332,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval
        zval *property = NULL;
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -25994,8 +26344,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -26013,8 +26364,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -26056,15 +26408,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -26109,7 +26463,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *re
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -26127,9 +26481,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *re
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
 
@@ -26154,9 +26507,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *re
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -26276,25 +26628,27 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_AR
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
-
-       if (IS_UNUSED == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = NULL;
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
+       zval *dim = NULL;
 
-       if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_CV == IS_VAR && 0 &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
                }
+       } else {
+               if (IS_UNUSED == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
+               }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
 
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -26313,16 +26667,38 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+
+               zval *property_name = NULL;
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+
+               }
        } else {
-               zend_free_op free_op_data1;
+               zend_free_op free_op_data1, free_op_data2;
                zval *value;
                zval *dim = NULL;
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -26668,7 +27044,6 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binary_op)(zval *re
        zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
        zval *value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
        znode *result = &opline->result;
-       zval **retval = &EX_T(result->u.var).var.ptr;
        int have_get_ptr = 0;
 
        EX_T(result->u.var).var.ptr_ptr = NULL;
@@ -26681,8 +27056,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binary_op)(zval *re
                FREE_OP(free_op_data1);
 
                if (!RETURN_VALUE_UNUSED(result)) {
-                       *retval = EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*retval);
+                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
        } else {
                /* here we are sure we are dealing with an object */
@@ -26700,8 +27076,9 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binary_op)(zval *re
                                have_get_ptr = 1;
                                binary_op(*zptr, *zptr, value TSRMLS_CC);
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = *zptr;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = *zptr;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(*zptr);
                                }
                        }
                }
@@ -26743,15 +27120,17 @@ static int zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binary_op)(zval *re
                                                break;
                                }
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = z;
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = z;
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(z);
                                }
                                zval_ptr_dtor(&z);
                        } else {
                                zend_error(E_WARNING, "Attempt to assign property of non-object");
                                if (!RETURN_VALUE_UNUSED(result)) {
-                                       *retval = EG(uninitialized_zval_ptr);
-                                       PZVAL_LOCK(*retval);
+                                       EX_T(result->u.var).var.ptr = EG(uninitialized_zval_ptr);
+                                       EX_T(result->u.var).var.ptr_ptr = NULL;
+                                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                                }
                        }
                }
@@ -26796,7 +27175,7 @@ static int zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op)(zval *result
 
                                        zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-                                       var_ptr = get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
+                                       var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
                                        increment_opline = 1;
                                }
                        }
@@ -26814,9 +27193,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op)(zval *result
 
        if (*var_ptr == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       EX_T(opline->result.u.var).var.ptr_ptr = &EG(uninitialized_zval_ptr);
-                       PZVAL_LOCK(*EX_T(opline->result.u.var).var.ptr_ptr);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
                }
 
 
@@ -26841,9 +27219,8 @@ static int zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op)(zval *result
        }
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = var_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *var_ptr);
                PZVAL_LOCK(*var_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
        if (increment_opline) {
@@ -27104,7 +27481,7 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
 
 
        ZEND_VM_NEXT_OPCODE();
@@ -27165,7 +27542,7 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC);
 
 
        ZEND_VM_NEXT_OPCODE();
@@ -27175,25 +27552,27 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
        zend_free_op free_op1;
-       int type = ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)?BP_VAR_W:BP_VAR_R;
-       zval *dim;
-
-       if (IS_CV == IS_UNUSED && type == BP_VAR_R) {
-               zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
-       }
-       dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
-       zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC), dim, 0, type TSRMLS_CC);
+       zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
 
-       if (IS_CV == IS_VAR && type == BP_VAR_W && 0 &&
-           READY_TO_DESTROY(free_op1.var) &&
-           !RETURN_VALUE_UNUSED(&opline->result)) {
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
-               if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
-                   Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
-                       SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+       if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) {
+               zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC);
+               if (IS_CV == IS_VAR && 0 &&
+                   READY_TO_DESTROY(free_op1.var) &&
+                   !RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) &&
+                           Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) {
+                               SEPARATE_ZVAL(EX_T(opline->result.u.var).var.ptr_ptr);
+                       }
+               }
+       } else {
+               if (IS_CV == IS_UNUSED) {
+                       zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
+               zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC);
        }
 
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -27244,20 +27623,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int zend_fetch_property_address_read_helper_SPEC_CV_CV(int type, ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zval *container;
-       zval **retval;
-
 
-       retval = &EX_T(opline->result.u.var).var.ptr;
-       EX_T(opline->result.u.var).var.ptr_ptr = retval;
-
-       container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
+       zval *container = _get_zval_ptr_cv(&opline->op1, EX(Ts), type TSRMLS_CC);
 
        if (container == EG(error_zval_ptr)) {
                if (!RETURN_VALUE_UNUSED(&opline->result)) {
-                       *retval = EG(error_zval_ptr);
-                       PZVAL_LOCK(*retval);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
+                       PZVAL_LOCK(EG(error_zval_ptr));
                }
 
                ZEND_VM_NEXT_OPCODE();
@@ -27268,26 +27640,30 @@ static int zend_fetch_property_address_read_helper_SPEC_CV_CV(int type, ZEND_OPC
                if (type != BP_VAR_IS) {
                        zend_error(E_NOTICE, "Trying to get property of non-object");
                }
-               *retval = EG(uninitialized_zval_ptr);
-               SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
+                       PZVAL_LOCK(EG(uninitialized_zval_ptr));
+               }
        } else {
 
                zval *offset  = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+               zval *retval;
 
                if (0) {
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
                /* here we are sure we are dealing with an object */
-               *retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
+               retval = Z_OBJ_HT_P(container)->read_property(container, offset, type TSRMLS_CC);
 
-               if (RETURN_VALUE_UNUSED(&opline->result) && (Z_REFCOUNT_PP(retval) == 0)) {
-                       zval_dtor(*retval);
-                       FREE_ZVAL(*retval);
+               if (RETURN_VALUE_UNUSED(&opline->result)) {
+                       if (Z_REFCOUNT_P(retval) == 0) {
+                               zval_dtor(retval);
+                               FREE_ZVAL(retval);
+                       }
                } else {
-                       SELECTIVE_PZVAL_LOCK(*retval, &opline->result);
-                       AI_USE_PTR(EX_T(opline->result.u.var).var);
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, retval);
+                       PZVAL_LOCK(retval);
                }
 
                if (0) {
@@ -27458,8 +27834,17 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *op_data = opline+1;
 
        zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+       zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+
+       if (0) {
+               MAKE_REAL_ZVAL_PTR(property_name);
+       }
+       zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       if (0) {
+               zval_ptr_dtor(&property_name);
+       } else {
 
-       zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC);
+       }
 
        /* assign_obj has two opcodes! */
        ZEND_VM_INC_OPCODE();
@@ -27481,16 +27866,38 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        }
 
        if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
-               zend_assign_to_object(&opline->result, object_ptr, &opline->op2, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+
+               zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+
+               if (0) {
+                       MAKE_REAL_ZVAL_PTR(property_name);
+               }
+               zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_DIM TSRMLS_CC);
+               if (0) {
+                       zval_ptr_dtor(&property_name);
+               } else {
+
+               }
        } else {
-               zend_free_op free_op_data1;
+               zend_free_op free_op_data1, free_op_data2;
                zval *value;
                zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+               zval **variable_ptr_ptr;
 
                zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
-               zend_assign_to_variable(&opline->result, &op_data->op2, &op_data->op1, value, (IS_TMP_FREE(free_op_data1)?IS_TMP_VAR:op_data->op1.op_type), EX(Ts) TSRMLS_CC);
+               variable_ptr_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
+               if (!variable_ptr_ptr) {
+                       zend_assign_to_string_offset(&EX_T(op_data->op2.u.var), value, op_data->op1.op_type TSRMLS_CC);
+               } else {
+                       value = zend_assign_to_variable(variable_ptr_ptr, value, IS_TMP_FREE(free_op_data1) TSRMLS_CC);
+               }
+               if (!RETURN_VALUE_UNUSED(&opline->result)) {
+                       AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+                       PZVAL_LOCK(value);
+               }
+               FREE_OP_VAR_PTR(free_op_data2);
                FREE_OP_IF_VAR(free_op_data1);
        }
 
@@ -27504,8 +27911,19 @@ static int ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_op *opline = EX(opline);
 
        zval *value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
+       zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+
+       if (!variable_ptr_ptr) {
+               zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC);
+       } else {
+               value = zend_assign_to_variable(variable_ptr_ptr, value, 0 TSRMLS_CC);
+       }
+
+       if (!RETURN_VALUE_UNUSED(&opline->result)) {
+               AI_SET_PTR(EX_T(opline->result.u.var).var, value);
+               PZVAL_LOCK(value);
+       }
 
-       zend_assign_to_variable(&opline->result, &opline->op1, &opline->op2, value, (0?IS_TMP_VAR:IS_CV), EX(Ts) TSRMLS_CC);
        /* zend_assign_to_variable() always takes care of op2, never free it! */
 
        ZEND_VM_NEXT_OPCODE();
@@ -27537,9 +27955,8 @@ static int ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC);
 
        if (!RETURN_VALUE_UNUSED(&opline->result)) {
-               EX_T(opline->result.u.var).var.ptr_ptr = variable_ptr_ptr;
+               AI_SET_PTR(EX_T(opline->result.u.var).var, *variable_ptr_ptr);
                PZVAL_LOCK(*variable_ptr_ptr);
-               AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
 
@@ -27627,7 +28044,7 @@ static int ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                 */
 
                EX_T(opline->op1.u.var).var.ptr_ptr = NULL;
-               AI_USE_PTR(EX_T(opline->op1.u.var).var);
+               EX_T(opline->op1.u.var).var.ptr = NULL;
        }
        ZEND_VM_NEXT_OPCODE();
 }