]> granicus.if.org Git - php/commitdiff
Added specialized handler for ZEND_FETCH_DIM_R opcode with only numeric indexes.
authorDmitry Stogov <dmitry@zend.com>
Wed, 18 May 2016 12:06:49 +0000 (15:06 +0300)
committerDmitry Stogov <dmitry@zend.com>
Wed, 18 May 2016 12:06:49 +0000 (15:06 +0300)
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 8522523d94f8e2255e30048b1e2b755fdc1136aa..93ff58e8070fe64e8daa367cec3025f3397f478f 100644 (file)
@@ -8463,4 +8463,52 @@ ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDE
        ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_TYPE_SPEC_HANDLER(ZEND_FETCH_DIM_R, (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))), ZEND_FETCH_DIM_R_INDEX, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
+{
+       USE_OPLINE
+       zend_free_op free_op1, free_op2;
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+       dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+ZEND_VM_C_LABEL(fetch_dim_r_index_array):
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, ZEND_VM_C_LABEL(fetch_dim_r_index_undef));
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (OP1_TYPE & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+                       FREE_OP1();
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (OP1_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       ZEND_VM_C_GOTO(fetch_dim_r_index_array);
+               } else {
+                       ZEND_VM_C_GOTO(fetch_dim_r_index_slow);
+               }
+       } else {
+ZEND_VM_C_LABEL(fetch_dim_r_index_slow):
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+               FREE_OP1();
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+ZEND_VM_C_LABEL(fetch_dim_r_index_undef):
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+       FREE_OP1();
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
index 2424a636dd3e8ff6fc84a773b2a1b3c38a6bfd9b..1b673b8c2a5ed0a67e886574640912801aef8522 100644 (file)
@@ -6280,6 +6280,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
        ZEND_VM_RETURN();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = EX_CONSTANT(opline->op1);
+       dim = EX_CONSTANT(opline->op2);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -9848,6 +9896,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
        ZEND_VM_RETURN();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = EX_CONSTANT(opline->op1);
+       dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -11525,6 +11621,54 @@ isset_no_object:
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op2;
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = EX_CONSTANT(opline->op1);
+       dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (IS_CONST & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -42872,6 +43016,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+       dim = EX_CONSTANT(opline->op2);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -49604,6 +49796,54 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
        ZEND_VM_RETURN();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+       dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -53508,6 +53748,54 @@ isset_no_object:
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op2;
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+       dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if (IS_CV & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -55543,6 +55831,54 @@ try_instanceof:
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+       dim = EX_CONSTANT(opline->op2);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+                       zval_ptr_dtor_nogc(free_op1);
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+               zval_ptr_dtor_nogc(free_op1);
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+       zval_ptr_dtor_nogc(free_op1);
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_static_prop_helper_SPEC_TMPVAR_VAR(int type ZEND_OPCODE_HANDLER_ARGS_DC)
 {
        USE_OPLINE
@@ -57633,6 +57969,54 @@ isset_no_object:
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+       dim = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+                       zval_ptr_dtor_nogc(free_op1);
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+               zval_ptr_dtor_nogc(free_op1);
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+       zval_ptr_dtor_nogc(free_op1);
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -58822,6 +59206,54 @@ isset_no_object:
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
 
+static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1, free_op2;
+       zval *container, *dim, *value;
+       zend_long offset;
+
+       container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+       dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+       if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+fetch_dim_r_index_array:
+               if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
+                       offset = Z_LVAL_P(dim);
+               } else {
+                       offset = zval_get_long(dim);
+               }
+               ZEND_HASH_INDEX_FIND(Z_ARRVAL_P(container), offset, value, fetch_dim_r_index_undef);
+               ZVAL_COPY(EX_VAR(opline->result.var), value);
+               if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) {
+                       SAVE_OPLINE();
+                       zval_ptr_dtor_nogc(free_op1);
+                       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+               } else {
+                       ZEND_VM_NEXT_OPCODE();
+               }
+       } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
+               container = Z_REFVAL_P(container);
+               if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+                       goto fetch_dim_r_index_array;
+               } else {
+                       goto fetch_dim_r_index_slow;
+               }
+       } else {
+fetch_dim_r_index_slow:
+               SAVE_OPLINE();
+               zend_fetch_dimension_address_read_R_slow(EX_VAR(opline->result.var), container, dim);
+               zval_ptr_dtor_nogc(free_op1);
+               ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+       }
+
+fetch_dim_r_index_undef:
+       ZVAL_NULL(EX_VAR(opline->result.var));
+       SAVE_OPLINE();
+       zend_error(E_NOTICE, "Undefined offset: " ZEND_LONG_FMT, offset);
+       zval_ptr_dtor_nogc(free_op1);
+       ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+}
+
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_TMPVARCV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -64198,6 +64630,31 @@ void zend_init_opcodes_handlers(void)
                ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER,
                ZEND_NULL_HANDLER,
                ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CONST_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVAR_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_CV_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVAR_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CV_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVAR_HANDLER,
+               ZEND_NULL_HANDLER,
+               ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CV_HANDLER,
                ZEND_NULL_HANDLER
        };
        static const uint32_t specs[] = {
@@ -64250,9 +64707,9 @@ void zend_init_opcodes_handlers(void)
                1423 | SPEC_RULE_OP1,
                1428 | SPEC_RULE_OP1,
                1433 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-               4446,
-               4446,
-               4446,
+               4471,
+               4471,
+               4471,
                1458 | SPEC_RULE_OP1,
                1463 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                1488 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
@@ -64301,7 +64758,7 @@ void zend_init_opcodes_handlers(void)
                2197 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                2222 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                2247 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-               4446,
+               4471,
                2272,
                2273,
                2274,
@@ -64385,7 +64842,7 @@ void zend_init_opcodes_handlers(void)
                3446 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                3471 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
                3496 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
-               4446
+               4471
        };
        zend_opcode_handlers = labels;
                zend_handlers_count = sizeof(labels) / sizeof(void*);
@@ -64666,6 +65123,11 @@ ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint
                                spec = 4431 | SPEC_RULE_OP1;
                        }
                        break;
+               case ZEND_FETCH_DIM_R:
+                       if ((!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)))) {
+                               spec = 4446 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
+                       }
+                       break;
                default:
                        break;
        }