]> granicus.if.org Git - php/commitdiff
Optimized ZEND_FETCH_DIM_*
authorDmitry Stogov <dmitry@zend.com>
Fri, 4 Apr 2014 21:56:51 +0000 (01:56 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 4 Apr 2014 21:56:51 +0000 (01:56 +0400)
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 05407efd868bcdc485ba56b68caa00598c987806..3e574e7491fda34f3dfe396da09835eeeaf76637 100644 (file)
@@ -982,361 +982,358 @@ static inline HashTable *zend_get_target_symbol_table(int fetch_type TSRMLS_DC)
        return NULL;
 }
 
-static inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
+static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type TSRMLS_DC)
 {
        zval *retval;
        zend_string *offset_key;
        ulong hval;
 
-       switch (Z_TYPE_P(dim)) {
-               case IS_NULL:
-                       offset_key = STR_EMPTY_ALLOC();
-                       goto fetch_string_dim;
-
-               case IS_STRING:
-                       offset_key = Z_STR_P(dim);
-                       if (dim_type != IS_CONST) {
-                               ZEND_HANDLE_NUMERIC_EX(offset_key->val, offset_key->len + 1, hval, goto num_index);
+       if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+               hval = Z_LVAL_P(dim);
+num_index:
+               retval = zend_hash_index_find(ht, hval);
+               if (retval == NULL) {
+                       switch (type) {
+                               case BP_VAR_R:
+                                       zend_error(E_NOTICE,"Undefined offset: %ld", hval);
+                                       /* break missing intentionally */
+                               case BP_VAR_UNSET:
+                               case BP_VAR_IS:
+                                       retval = &EG(uninitialized_zval);
+                                       break;
+                               case BP_VAR_RW:
+                                       zend_error(E_NOTICE,"Undefined offset: %ld", hval);
+                                       /* break missing intentionally */
+                               case BP_VAR_W:
+                                       retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
+                                       break;
                        }
-fetch_string_dim:
-                       retval = zend_hash_find(ht, offset_key);
-// ??? support for $GLOBALS[...]
-                       if (retval) {
-                               if (Z_TYPE_P(retval) == IS_INDIRECT) {
-                                       retval = Z_INDIRECT_P(retval);
-                                       if (Z_TYPE_P(retval) == IS_UNDEF) {
-                                               switch (type) {
-                                                       case BP_VAR_R:
-                                                               zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
-                                                               /* break missing intentionally */
-                                                       case BP_VAR_UNSET:
-                                                       case BP_VAR_IS:
-                                                               retval = &EG(uninitialized_zval);
-                                                               break;
-                                                       case BP_VAR_RW:
-                                                               zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
-                                                               /* break missing intentionally */
-                                                       case BP_VAR_W:
-                                                               ZVAL_NULL(retval);
-                                                               break;
-                                               }
+               }
+       } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) {
+               offset_key = Z_STR_P(dim);
+               if (dim_type != IS_CONST) {
+                       ZEND_HANDLE_NUMERIC_EX(offset_key->val, offset_key->len+1, hval, goto num_index);
+               }
+str_index:
+               retval = zend_hash_find(ht, offset_key);
+               if (retval) {
+                       /* support for $GLOBALS[...] */
+                       if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT)) {
+                               retval = Z_INDIRECT_P(retval);
+                               if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) {
+                                       switch (type) {
+                                               case BP_VAR_R:
+                                                       zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
+                                                       /* break missing intentionally */
+                                               case BP_VAR_UNSET:
+                                               case BP_VAR_IS:
+                                                       retval = &EG(uninitialized_zval);
+                                                       break;
+                                               case BP_VAR_RW:
+                                                       zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
+                                                       /* break missing intentionally */
+                                               case BP_VAR_W:
+                                                       ZVAL_NULL(retval);
+                                                       break;
                                        }
                                }
-                       } else { 
-                               switch (type) {
-                                       case BP_VAR_R:
-                                               zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
-                                               /* break missing intentionally */
-                                       case BP_VAR_UNSET:
-                                       case BP_VAR_IS:
-                                               retval = &EG(uninitialized_zval);
-                                               break;
-                                       case BP_VAR_RW:
-                                               zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
-                                               /* break missing intentionally */
-                                       case BP_VAR_W:
-                                               retval = zend_hash_update(ht, offset_key, &EG(uninitialized_zval));
-                                               break;
-                               }
                        }
-                       break;
-               case IS_DOUBLE:
-                       hval = zend_dval_to_lval(Z_DVAL_P(dim));
-                       goto num_index;
-               case IS_RESOURCE:
-                       zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
-                       hval = Z_RES_HANDLE_P(dim);
-                       goto num_index;
-               case IS_BOOL:
-               case IS_LONG:
-                       hval = Z_LVAL_P(dim);
-num_index:
-                       retval = zend_hash_index_find(ht, hval);
-                       if (retval == NULL) {
-                               switch (type) {
-                                       case BP_VAR_R:
-                                               zend_error(E_NOTICE,"Undefined offset: %ld", hval);
-                                               /* break missing intentionally */
-                                       case BP_VAR_UNSET:
-                                       case BP_VAR_IS:
-                                               retval = &EG(uninitialized_zval);
-                                               break;
-                                       case BP_VAR_RW:
-                                               zend_error(E_NOTICE,"Undefined offset: %ld", hval);
-                                               /* break missing intentionally */
-                                       case BP_VAR_W:
-                                               retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval));
-                                               break;
-                               }
+               } else { 
+                       switch (type) {
+                               case BP_VAR_R:
+                                       zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
+                                       /* break missing intentionally */
+                               case BP_VAR_UNSET:
+                               case BP_VAR_IS:
+                                       retval = &EG(uninitialized_zval);
+                                       break;
+                               case BP_VAR_RW:
+                                       zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
+                                       /* break missing intentionally */
+                               case BP_VAR_W:
+                                       retval = zend_hash_update(ht, offset_key, &EG(uninitialized_zval));
+                                       break;
                        }
-                       break;
-
-               default:
-                       zend_error(E_WARNING, "Illegal offset type");
-                       return (type == BP_VAR_W || type == BP_VAR_RW) ?
-                               &EG(error_zval) : &EG(uninitialized_zval);
+               }
+       } else {
+               switch (Z_TYPE_P(dim)) {
+                       case IS_NULL:
+                               offset_key = STR_EMPTY_ALLOC();
+                               goto str_index;
+                       case IS_DOUBLE:
+                               hval = zend_dval_to_lval(Z_DVAL_P(dim));
+                               goto num_index;
+                       case IS_RESOURCE:
+                               zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_RES_HANDLE_P(dim), Z_RES_HANDLE_P(dim));
+                               hval = Z_RES_HANDLE_P(dim);
+                               goto num_index;
+                       case IS_BOOL:
+                               hval = Z_LVAL_P(dim);
+                               goto num_index;
+                       default:
+                               zend_error(E_WARNING, "Illegal offset type");
+                               retval = (type == BP_VAR_W || type == BP_VAR_RW) ?
+                                       &EG(error_zval) : &EG(uninitialized_zval);
+               }
        }
        return retval;
 }
 
-static void zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref TSRMLS_DC)
+static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref TSRMLS_DC)
 {
     zval *retval;
     zval *container = container_ptr;
 
        ZVAL_DEREF(container);
-       switch (Z_TYPE_P(container)) {
-               case IS_ARRAY:
-                       if (container == container_ptr) {
-                               SEPARATE_ZVAL(container);
-                       }
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+               if (container == container_ptr) {
+                       SEPARATE_ZVAL(container);
+               }
 fetch_from_array:
-                       if (dim == NULL) {
-                               retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
-                               if (retval == NULL) {
-                                       zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
-                                       retval = &EG(error_zval);
-                               }
-                       } else {
-                               retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
-                       }
-                       if (is_ref) {
-                               SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
-                               ZVAL_COPY(result, retval);
-                       } else {
-                               ZVAL_INDIRECT(result, retval);
+               if (dim == NULL) {
+                       retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
+                       if (retval == NULL) {
+                               zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
+                               retval = &EG(error_zval);
                        }
-                       break;
-
-               case IS_NULL:
-                       if (container == &EG(error_zval)) {
-                               ZVAL_INDIRECT(result, &EG(error_zval));
-                       } else if (type != BP_VAR_UNSET) {
+               } else {
+                       retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
+               }
+               if (is_ref) {
+                       SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+                       ZVAL_COPY(result, retval);
+               } else {
+                       ZVAL_INDIRECT(result, retval);
+               }
+       } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+               if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
 convert_to_array:
-                               array_init(container);
-                               goto fetch_from_array;
-                       } else {
-                               /* for read-mode only */
-                               ZVAL_NULL(result);
-                       }
-                       break;
+                       array_init(container);
+                       goto fetch_from_array;
+               }
+               if (dim == NULL) {
+                       zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
+               }
 
-               case IS_STRING: {
-                               zval tmp;
+               if (type != BP_VAR_UNSET) {
+                       if (container == container_ptr) {
+                               SEPARATE_ZVAL(container);
+                       }
+               }
 
-                               if (type != BP_VAR_UNSET && Z_STRLEN_P(container)==0) {
-                                       goto convert_to_array;
-                               }
-                               if (dim == NULL) {
-                                       zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
-                               }
+               if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
+                       zval tmp;
 
-                               if (type != BP_VAR_UNSET) {
-                                       if (container == container_ptr) {
-                                               SEPARATE_ZVAL(container);
+                       switch(Z_TYPE_P(dim)) {
+                               case IS_STRING:
+                                       if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
+                                               break;
                                        }
-                               }
-
-                               if (Z_TYPE_P(dim) != IS_LONG) {
-
-                                       switch(Z_TYPE_P(dim)) {
-                                               /* case IS_LONG: */
-                                               case IS_STRING:
-                                                       if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
-                                                               break;
-                                                       }
-                                                       if (type != BP_VAR_UNSET) {
-                                                               zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
-                                                       }
-
-                                                       break;
-                                               case IS_DOUBLE:
-                                               case IS_NULL:
-                                               case IS_BOOL:
-                                                       zend_error(E_NOTICE, "String offset cast occurred");
-                                                       break;
-                                               default:
-                                                       zend_error(E_WARNING, "Illegal offset type");
-                                                       break;
+                                       if (type != BP_VAR_UNSET) {
+                                               zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
                                        }
-
-                                       ZVAL_DUP(&tmp, dim);
-                                       convert_to_long(&tmp);
-                                       dim = &tmp;
-                               }
-                               ZVAL_STR_OFFSET(result, container, Z_LVAL_P(dim));
-                               if (!IS_INTERNED(Z_STR_P(container))) STR_ADDREF(Z_STR_P(container));
+                                       break;
+                               case IS_DOUBLE:
+                               case IS_NULL:
+                               case IS_BOOL:
+                                       zend_error(E_NOTICE, "String offset cast occurred");
+                                       break;
+                               default:
+                                       zend_error(E_WARNING, "Illegal offset type");
+                                       break;
                        }
-                       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_type == 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, result TSRMLS_CC);
-
-                               if (overloaded_result && Z_TYPE_P(overloaded_result) != IS_UNDEF) {
-                                       if (!Z_ISREF_P(overloaded_result)) {
-                                               if (Z_REFCOUNTED_P(overloaded_result) &&
-                                                   Z_REFCOUNT_P(overloaded_result) > 1) {
-                                                       if (Z_TYPE_P(overloaded_result) != IS_OBJECT) {
-                                                               Z_DELREF_P(overloaded_result);
-                                                               ZVAL_DUP(result, overloaded_result);
-                                                               overloaded_result = result;
-                                                       } else {
-                                                               ZVAL_COPY(result, overloaded_result);
-                                                               overloaded_result = result;
-                                                       }
-                                               }
-                                               if (Z_TYPE_P(overloaded_result) != IS_OBJECT) {
-                                                       zend_class_entry *ce = Z_OBJCE_P(container);
-                                                       zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
-                                               }
-                                       }
-//???                                  AI_SET_PTR(result, overloaded_result);
-//???                                  PZVAL_LOCK(overloaded_result);
-//???                                  ZVAL_COPY(result, overloaded_result);
-                                       if (result != overloaded_result) {
-                                               if (is_ref && overloaded_result != &EG(uninitialized_zval)) {
-                                                       SEPARATE_ZVAL_TO_MAKE_IS_REF(overloaded_result);
-                                                       ZVAL_COPY(result, overloaded_result);
+                       ZVAL_DUP(&tmp, dim);
+                       convert_to_long(&tmp);
+                       dim = &tmp;
+               }
+
+               if (!IS_INTERNED(Z_STR_P(container))) STR_ADDREF(Z_STR_P(container));
+               ZVAL_STR_OFFSET(result, container, Z_LVAL_P(dim));
+       } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+               if (!Z_OBJ_HT_P(container)->read_dimension) {
+                       zend_error_noreturn(E_ERROR, "Cannot use object as array");
+               } else {
+//???                  if (dim_type == IS_TMP_VAR) {
+//???                          zval *orig = dim;
+//???                          MAKE_REAL_ZVAL_PTR(dim);
+//???                          ZVAL_NULL(orig);
+//???                  }
+                       retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result TSRMLS_CC);
+
+                       if (retval && Z_TYPE_P(retval) != IS_UNDEF) {
+                               if (!Z_ISREF_P(retval)) {
+                                       if (Z_REFCOUNTED_P(retval) &&
+                                           Z_REFCOUNT_P(retval) > 1) {
+                                               if (Z_TYPE_P(retval) != IS_OBJECT) {
+                                                       Z_DELREF_P(retval);
+                                                       ZVAL_DUP(result, retval);
+                                                       retval = result;
                                                } else {
-                                                       ZVAL_INDIRECT(result, overloaded_result);
+                                                       ZVAL_COPY(result, retval);
+                                                       retval = result;
                                                }
                                        }
-                               } else {
-                                       ZVAL_INDIRECT(result, &EG(error_zval));
+                                       if (Z_TYPE_P(retval) != IS_OBJECT) {
+                                               zend_class_entry *ce = Z_OBJCE_P(container);
+                                               zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
+                                       }
+                               }
+//???                          AI_SET_PTR(result, retval);
+//???                          PZVAL_LOCK(retval);
+//???                          ZVAL_COPY(result, retval);
+                               if (result != retval) {
+                                       if (is_ref && retval != &EG(uninitialized_zval)) {
+                                               SEPARATE_ZVAL_TO_MAKE_IS_REF(retval);
+                                               ZVAL_COPY(result, retval);
+                                       } else {
+                                               ZVAL_INDIRECT(result, retval);
+                                       }
                                }
-//???                          if (dim_type == IS_TMP_VAR) {
-//???                                  zval_ptr_dtor(dim);
-//???                          }
-                       }
-                       break;
-
-               case IS_BOOL:
-                       if (type != BP_VAR_UNSET && Z_LVAL_P(container)==0) {
-                               goto convert_to_array;
-                       }
-                       /* break missing intentionally */
-
-               default:
-                       if (type == BP_VAR_UNSET) {
-                               zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
-                               ZVAL_NULL(result);
                        } else {
-                               zend_error(E_WARNING, "Cannot use a scalar value as an array");
                                ZVAL_INDIRECT(result, &EG(error_zval));
                        }
-                       break;
+//???                  if (dim_type == IS_TMP_VAR) {
+//???                          zval_ptr_dtor(dim);
+//???                  }
+               }
+       } else if (EXPECTED(Z_TYPE_P(container) == IS_NULL)) {
+               if (container == &EG(error_zval)) {
+                       ZVAL_INDIRECT(result, &EG(error_zval));
+               } else if (type != BP_VAR_UNSET) {
+                       goto convert_to_array;
+               } else {
+                       /* for read-mode only */
+                       ZVAL_NULL(result);
+               }
+       } else {
+               if (type != BP_VAR_UNSET &&
+                   Z_TYPE_P(container) == IS_BOOL &&
+                   Z_LVAL_P(container)==0) {
+                       goto convert_to_array;
+               }
+               if (type == BP_VAR_UNSET) {
+                       zend_error(E_WARNING, "Cannot unset offset in a non-array variable");
+                       ZVAL_NULL(result);
+               } else {
+                       zend_error(E_WARNING, "Cannot use a scalar value as an array");
+                       ZVAL_INDIRECT(result, &EG(error_zval));
+               }
        }
 }
 
-static void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
+static zend_never_inline void zend_fetch_dimension_address_W(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
 {
-       zval *retval;
-
-       ZVAL_DEREF(container);
-       switch (Z_TYPE_P(container)) {
+       zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0 TSRMLS_CC);
+}
 
-               case IS_ARRAY:
-                       retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
-                       ZVAL_COPY(result, retval);
-                       return;
+static zend_never_inline void zend_fetch_dimension_address_W_ref(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
+{
+       zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1 TSRMLS_CC);
+}
 
-               case IS_NULL:
-                       ZVAL_NULL(result);
-                       return;
+static zend_never_inline void zend_fetch_dimension_address_RW(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
+{
+       zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0 TSRMLS_CC);
+}
 
-               case IS_STRING: {
-                               zval tmp;
-
-                               if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
-                                       switch(Z_TYPE_P(dim)) {
-                                               /* case IS_LONG: */
-                                               case IS_STRING:
-                                                       if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
-                                                               break;
-                                                       }
-                                                       if (type != BP_VAR_IS) {
-                                                               zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
-                                                       }
-                                                       break;
-                                               case IS_DOUBLE:
-                                               case IS_NULL:
-                                               case IS_BOOL:
-                                                       if (type != BP_VAR_IS) {
-                                                               zend_error(E_NOTICE, "String offset cast occurred");
-                                                       }
-                                                       break;
-                                               default:
-                                                       zend_error(E_WARNING, "Illegal offset type");
-                                                       break;
-                                       }
+static zend_never_inline void zend_fetch_dimension_address_UNSET(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
+{
+       zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0 TSRMLS_CC);
+}
 
-                                       ZVAL_DUP(&tmp, dim);
-                                       convert_to_long(&tmp);
-                                       dim = &tmp;
-                               }
+static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
+{
+       zval *retval;
 
-                               if (UNEXPECTED(Z_LVAL_P(dim) < 0) || UNEXPECTED(Z_STRLEN_P(container) <= Z_LVAL_P(dim))) {
+       ZVAL_DEREF(container);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+               retval = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, dim_type, type TSRMLS_CC);
+               ZVAL_COPY(result, retval);
+       } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
+               if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
+                       zval tmp;
+
+                       switch(Z_TYPE_P(dim)) {
+                               /* case IS_LONG: */
+                               case IS_STRING:
+                                       if (IS_LONG == is_numeric_string(Z_STRVAL_P(dim), Z_STRLEN_P(dim), NULL, NULL, -1)) {
+                                               break;
+                                       }
                                        if (type != BP_VAR_IS) {
-                                               zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
+                                               zend_error(E_WARNING, "Illegal string offset '%s'", Z_STRVAL_P(dim));
                                        }
-                                       ZVAL_EMPTY_STRING(result);
-                               } else {
-                                       zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[Z_LVAL_P(dim)];
-                                       
-                                       if (CG(one_char_string)[c]) {
-                                               ZVAL_INT_STR(result, CG(one_char_string)[c]);
-                                       } else {
-                                               ZVAL_NEW_STR(result, STR_INIT(Z_STRVAL_P(container) + Z_LVAL_P(dim), 1, 0));
+                                       break;
+                               case IS_DOUBLE:
+                               case IS_NULL:
+                               case IS_BOOL:
+                                       if (type != BP_VAR_IS) {
+                                               zend_error(E_NOTICE, "String offset cast occurred");
                                        }
-                               }
-                               return;
+                                       break;
+                               default:
+                                       zend_error(E_WARNING, "Illegal offset type");
+                                       break;
                        }
-                       break;
 
-               case IS_OBJECT:
-                       if (!Z_OBJ_HT_P(container)->read_dimension) {
-                               zend_error_noreturn(E_ERROR, "Cannot use object as array");
+                       ZVAL_DUP(&tmp, dim);
+                       convert_to_long(&tmp);
+                       dim = &tmp;
+               }
+
+               if (UNEXPECTED(Z_LVAL_P(dim) < 0) || UNEXPECTED(Z_STRLEN_P(container) <= Z_LVAL_P(dim))) {
+                       if (type != BP_VAR_IS) {
+                               zend_error(E_NOTICE, "Uninitialized string offset: %ld", Z_LVAL_P(dim));
+                       }
+                       ZVAL_EMPTY_STRING(result);
+               } else {
+                       zend_uchar c = (zend_uchar)Z_STRVAL_P(container)[Z_LVAL_P(dim)];
+
+                       if (CG(one_char_string)[c]) {
+                               ZVAL_INT_STR(result, CG(one_char_string)[c]);
                        } else {
-                               zval *overloaded_result;
-
-//???                          if (dim_type == 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, result TSRMLS_CC);
-
-                               if (result) {
-                                       if (overloaded_result) {
-                                               if (result != overloaded_result) {
-                                                       ZVAL_COPY(result, overloaded_result);
-                                               }
-                                       } else {
-                                               ZVAL_NULL(result);
+                               ZVAL_NEW_STR(result, STR_INIT(Z_STRVAL_P(container) + Z_LVAL_P(dim), 1, 0));
+                       }
+               }
+       } else if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+               if (!Z_OBJ_HT_P(container)->read_dimension) {
+                       zend_error_noreturn(E_ERROR, "Cannot use object as array");
+               } else {
+//???                  if (dim_type == IS_TMP_VAR) {
+//???                          zval *orig = dim;
+//???                          MAKE_REAL_ZVAL_PTR(dim);
+//???                          ZVAL_NULL(orig);
+//???                  }
+                       retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result TSRMLS_CC);
+
+                       if (result) {
+                               if (retval) {
+                                       if (result != retval) {
+                                               ZVAL_COPY(result, retval);
                                        }
+                               } else {
+                                       ZVAL_NULL(result);
                                }
-//???                          if (dim_type == IS_TMP_VAR) {
-//???                                  zval_ptr_dtor(dim);
-//???                          }
                        }
-                       return;
-
-               default:
-                       ZVAL_NULL(result);
-                       return;
+//???                  if (dim_type == IS_TMP_VAR) {
+//???                          zval_ptr_dtor(dim);
+//???                  }
+               }
+       } else {
+               ZVAL_NULL(result);
        }
 }
 
+static zend_never_inline void zend_fetch_dimension_address_read_R(zval *result, zval *container, zval *dim, int dim_type TSRMLS_DC)
+{
+       zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_R TSRMLS_CC);
+}
+
+static zend_never_inline void zend_fetch_dimension_address_read_IS(zval *result, zval *container, zval *dim, int dim_type TSRMLS_DC)
+{
+       zend_fetch_dimension_address_read(result, container, dim, dim_type, BP_VAR_IS TSRMLS_CC);
+}
+
 static void zend_fetch_property_address(zval *result, zval *container_ptr, zval *prop_ptr, const zend_literal *key, int type, int is_ref TSRMLS_DC)
 {
        zval *container = container_ptr;
index 9dac4c73d2056b4936f03bc8eb36755b51db484d..07bd45ab94a6ed7f86d8b64c4ba315ee84f8576b 100644 (file)
@@ -455,7 +455,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
                                } else {
                                        zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, OP2_TYPE, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, OP2_TYPE TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -1165,7 +1165,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
 
        SAVE_OPLINE();
        container = GET_OP1_ZVAL_PTR(BP_VAR_R);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                FREE_OP1();
@@ -1186,7 +1186,11 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
        if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
+       }
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1208,7 +1212,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
        if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1226,7 +1230,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, VAR|CV, CONST|TMP|VAR|CV)
 
        SAVE_OPLINE();
        container = GET_OP1_ZVAL_PTR(BP_VAR_IS);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
        FREE_OP2();
        FREE_OP1();
        CHECK_EXCEPTION();
@@ -1246,7 +1250,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
                if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -1257,7 +1261,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = GET_OP1_ZVAL_PTR(BP_VAR_R);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
                FREE_OP2();
                FREE_OP1();
        }
@@ -1277,7 +1281,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
        if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && OP1_FREE && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1597,7 +1601,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
                FREE_OP2();
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
index bf06aa8a5fabfeb1d699ede4edd97d0a4a12b3c9..ee1ed712f7511f979236856a842569686a61a97d 100644 (file)
@@ -3692,7 +3692,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_
 
        SAVE_OPLINE();
        container = opline->op1.zv;
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -4642,7 +4642,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA
 
        SAVE_OPLINE();
        container = opline->op1.zv;
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -5467,7 +5467,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA
 
        SAVE_OPLINE();
        container = opline->op1.zv;
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -6949,7 +6949,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN
 
        SAVE_OPLINE();
        container = opline->op1.zv;
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -8799,7 +8799,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA
 
        SAVE_OPLINE();
        container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_dtor(free_op1.var);
@@ -9613,7 +9613,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_dtor(free_op1.var);
@@ -10438,7 +10438,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_dtor(free_op1.var);
@@ -11788,7 +11788,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL
 
        SAVE_OPLINE();
        container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_dtor(free_op1.var);
@@ -13956,7 +13956,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
                                } else {
                                        zval *dim = opline->op2.zv;
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -14448,7 +14448,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_ptr_dtor_nogc(free_op1.var);
@@ -14469,7 +14469,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
+       }
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14491,7 +14495,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14509,7 +14513,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -14529,7 +14533,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
                if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
                if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -14540,7 +14544,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
                zval_ptr_dtor_nogc(free_op1.var);
        }
@@ -14560,7 +14564,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14858,7 +14862,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
                zval *dim = opline->op2.zv;
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
@@ -16296,7 +16300,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
                                } else {
                                        zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -16617,7 +16621,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_ptr_dtor_nogc(free_op1.var);
@@ -16638,7 +16642,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
+       }
        zval_dtor(free_op2.var);
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -16660,7 +16668,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -16678,7 +16686,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -16698,7 +16706,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
                if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
                if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -16709,7 +16717,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
                zval_dtor(free_op2.var);
                zval_ptr_dtor_nogc(free_op1.var);
        }
@@ -16729,7 +16737,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -17027,7 +17035,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
                zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
@@ -18228,7 +18236,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
                                } else {
                                        zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -18721,7 +18729,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_ptr_dtor_nogc(free_op1.var);
@@ -18742,7 +18750,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
+       }
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18764,7 +18776,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18782,7 +18794,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -18802,7 +18814,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
                if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
                if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -18813,7 +18825,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
                zval_ptr_dtor_nogc(free_op2.var);
                zval_ptr_dtor_nogc(free_op1.var);
        }
@@ -18833,7 +18845,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -19131,7 +19143,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
                zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
                zval_ptr_dtor_nogc(free_op2.var);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
@@ -20268,7 +20280,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
                                } else {
                                        zval *dim = NULL;
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -20570,7 +20582,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
+       }
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20592,7 +20608,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20615,7 +20631,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
                if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
                if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -20626,7 +20642,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
 
                zval_ptr_dtor_nogc(free_op1.var);
        }
@@ -20668,7 +20684,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
                zval *dim = NULL;
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
@@ -21619,7 +21635,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
                                } else {
                                        zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -21939,7 +21955,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
                zval_ptr_dtor_nogc(free_op1.var);
@@ -21960,7 +21976,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
+       }
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -21982,7 +22002,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22000,7 +22020,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        zval_ptr_dtor_nogc(free_op1.var);
        CHECK_EXCEPTION();
@@ -22020,7 +22040,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
                if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
                if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -22031,7 +22051,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
                zval_ptr_dtor_nogc(free_op1.var);
        }
@@ -22051,7 +22071,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
        if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22349,7 +22369,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
                zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
@@ -23413,7 +23433,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
                                } else {
                                        zval *dim = opline->op2.zv;
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -24741,7 +24761,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
                                } else {
                                        zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -25984,7 +26004,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
                                } else {
                                        zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -27228,7 +27248,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
                                } else {
                                        zval *dim = NULL;
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -27626,7 +27646,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
                                } else {
                                        zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -30366,7 +30386,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
                                } else {
                                        zval *dim = opline->op2.zv;
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -30858,7 +30878,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -30879,7 +30899,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
+       }
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30901,7 +30925,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30919,7 +30943,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
 
        CHECK_EXCEPTION();
@@ -30939,7 +30963,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
                if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
                if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -30950,7 +30974,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
 
        }
@@ -30970,7 +30994,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -31266,7 +31290,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
                zval *dim = opline->op2.zv;
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
@@ -32490,7 +32514,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
                                } else {
                                        zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -32811,7 +32835,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -32832,7 +32856,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
+       }
        zval_dtor(free_op2.var);
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32854,7 +32882,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32872,7 +32900,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
 
        CHECK_EXCEPTION();
@@ -32892,7 +32920,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
                if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
                if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -32903,7 +32931,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
                zval_dtor(free_op2.var);
 
        }
@@ -32923,7 +32951,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
        zval_dtor(free_op2.var);
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -33219,7 +33247,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
                zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
                zval_dtor(free_op2.var);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
@@ -34299,7 +34327,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
                                } else {
                                        zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -34792,7 +34820,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -34813,7 +34841,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
+       }
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -34835,7 +34867,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -34853,7 +34885,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
 
        CHECK_EXCEPTION();
@@ -34873,7 +34905,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
                if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
                if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -34884,7 +34916,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
                zval_ptr_dtor_nogc(free_op2.var);
 
        }
@@ -34904,7 +34936,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
        zval_ptr_dtor_nogc(free_op2.var);
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35200,7 +35232,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
                zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
                zval_ptr_dtor_nogc(free_op2.var);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
@@ -36215,7 +36247,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
                                } else {
                                        zval *dim = NULL;
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -36517,7 +36549,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
+       }
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -36539,7 +36575,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -36562,7 +36598,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
                if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
                if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -36573,7 +36609,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
 
 
        }
@@ -36615,7 +36651,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
                zval *dim = NULL;
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
@@ -37431,7 +37467,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
                                } else {
                                        zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
 
-                                       zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW, 0 TSRMLS_CC);
+                                       zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
                                        value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                                        var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
                                }
@@ -37751,7 +37787,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
 
@@ -37772,7 +37808,11 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W, opline->extended_value != 0 TSRMLS_CC);
+       if (EXPECTED(opline->extended_value == 0)) {
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
+       } else {
+               zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
+       }
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37794,7 +37834,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37812,7 +37852,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
 
        SAVE_OPLINE();
        container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
 
        CHECK_EXCEPTION();
@@ -37832,7 +37872,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
                if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
                        zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
                }
-               zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
                if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                        EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
                }
@@ -37843,7 +37883,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
                        zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
                }
                container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-               zend_fetch_dimension_address_read(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+               zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
 
        }
@@ -37863,7 +37903,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
        if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) {
                zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
        }
-       zend_fetch_dimension_address(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET, 0 TSRMLS_CC);
+       zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
 
        if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
                EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -38159,7 +38199,7 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
                zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
                zval *variable_ptr;
 
-               zend_fetch_dimension_address(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV, BP_VAR_W, 0 TSRMLS_CC);
+               zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
 
                value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
                variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);