]> granicus.if.org Git - php/commitdiff
Implement const array/string dereference
authorXinchen Hui <laruence@php.net>
Sun, 15 Apr 2012 03:40:38 +0000 (11:40 +0800)
committerXinchen Hui <laruence@php.net>
Tue, 17 Apr 2012 02:06:17 +0000 (10:06 +0800)
RFC:https://wiki.php.net/rfc/constdereference

NEWS
UPGRADING
Zend/tests/const_dereference_001.phpt [new file with mode: 0644]
Zend/tests/const_dereference_002.phpt [new file with mode: 0644]
Zend/tests/const_dereference_003.phpt [new file with mode: 0644]
Zend/zend_language_parser.y
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 6aa804cab7e58948fa1dc1edb8e92ddfb23f327a..ecfaa9385d5ccb82d3b539911c73d88037e01c08 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ PHP                                                                        NEWS
   . Drop Windows XP and 2003 support. (Pierre)
   . World domination
   . Improve set_exception_handler while doing reset.(Laruence)
+  . Support constant array/string dereferencing. (Laruence)
 
 - Core:
   . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL).
index 575ff1b750e1ddec68be128de1e7a12a7fa55eb9..d6d6e9bb736c25065c2559f0b471f78358ac4697 100755 (executable)
--- a/UPGRADING
+++ b/UPGRADING
@@ -26,6 +26,8 @@ PHP X.Y UPGRADE NOTES
 2. New Features
 ========================================
 
+- Support constant array/string dereferencing. (Laruence)
+  (https://wiki.php.net/rfc/constdereference)
 
 ========================================
 2. Changes in SAPI modules
diff --git a/Zend/tests/const_dereference_001.phpt b/Zend/tests/const_dereference_001.phpt
new file mode 100644 (file)
index 0000000..5fe6e4d
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Const array deference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+var_dump(array(1, 2, 3, 4,) [3]);
+var_dump(array(1, 2, 3, 4,) ['foo']);
+var_dump(array(array(1,2,3), array(4, 5, 6))[1][2]);
+
+foreach (array(array(1, 2, 3))[0] as $var) {
+     echo $var;
+}
+?>
+--EXPECTF--
+int(4)
+
+Notice: Undefined index: foo in %sconst_dereference_001.php on line %d
+NULL
+int(6)
+123
diff --git a/Zend/tests/const_dereference_002.phpt b/Zend/tests/const_dereference_002.phpt
new file mode 100644 (file)
index 0000000..ff89519
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Const string dereference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+var_dump("foobar"[3]);
+var_dump("foobar"[2][0]);
+var_dump("foobar"["foo"]["bar"]);
+
+--EXPECTF--
+string(1) "b"
+string(1) "o"
+
+Warning: Illegal string offset 'foo' in %sconst_dereference_002.php on line %d
+
+Warning: Illegal string offset 'bar' in %sconst_dereference_002.php on line %d
+string(1) "f"
diff --git a/Zend/tests/const_dereference_003.phpt b/Zend/tests/const_dereference_003.phpt
new file mode 100644 (file)
index 0000000..810ad14
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Const array deference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+var_dump([1, 2, 3, 4,][3]);
+var_dump([1, 2, 3, 4]['foo']);
+var_dump([array(1,2,3), [4, 5, 6]][1][2]);
+
+foreach (array([1, 2, 3])[0] as $var) {
+     echo $var;
+}
+?>
+--EXPECTF--
+int(4)
+
+Notice: Undefined index: foo in %sconst_dereference_003.php on line %d
+NULL
+int(6)
+123
index d0730b75d6d4533422630df7aa68afff5e53d6d3..893e0133efe0f684681519479c1a6dc5d639dca4 100644 (file)
@@ -789,8 +789,8 @@ expr_without_variable:
        |       T_EXIT exit_expr        { zend_do_exit(&$$, &$2 TSRMLS_CC); }
        |       '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
        |       scalar                          { $$ = $1; }
-       |       T_ARRAY '(' array_pair_list ')' { $$ = $3; }
-       |       '[' array_pair_list ']' { $$ = $2; }
+       |       combined_scalar_offset { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); }
+       |       combined_scalar { $$ = $1; }
        |       '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
        |       T_PRINT expr  { zend_do_print(&$$, &$2 TSRMLS_CC); }
        |       function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
@@ -799,6 +799,15 @@ expr_without_variable:
                        parameter_list ')' lexical_vars '{' inner_statement_list '}' {  zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; }
 ;
 
+combined_scalar_offset:
+         combined_scalar '[' dim_offset ']' { zend_do_begin_variable_parse(TSRMLS_C); fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+       | combined_scalar_offset '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+    | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' { zend_do_begin_variable_parse(TSRMLS_C); fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+
+combined_scalar:
+      T_ARRAY '(' array_pair_list ')' { $$ = $3; }
+    | '[' array_pair_list ']' { $$ = $2; }
+
 function:
        T_FUNCTION { $$.u.op.opline_num = CG(zend_lineno); }
 ;
index 8cceb19d83affc3aeee221fecb4026dfc189dff3..7b13b440faacb2a8e26722a5fd1fd1d6c6144e4e 100644 (file)
@@ -1174,7 +1174,7 @@ ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS);
 }
 
-ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
+ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
 {
        USE_OPLINE
        zend_free_op free_op1, free_op2;
@@ -1187,10 +1187,19 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
-       FREE_OP2();
-       FREE_OP1_VAR_PTR();
+    
+    if (OP1_TYPE == IS_TMP_VAR || OP1_TYPE == IS_CONST) {
+        zval *container = GET_OP1_ZVAL_PTR(BP_VAR_R);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
+        FREE_OP2();
+        FREE_OP1();
+    } else {
+        container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_R);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, GET_OP2_ZVAL_PTR(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
+        FREE_OP2();
+        FREE_OP1_VAR_PTR();
+    }
+
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
index 68ba74b44005d2aaf1e1b456cbdd10da65c2a899..2096c44e66991382c4e6cf33f9d027380958809e 100644 (file)
@@ -3374,6 +3374,36 @@ static int ZEND_FASTCALL  ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN
        return zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_CONST != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) {
+        zval *container = opline->op1.zv;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -4200,6 +4230,36 @@ static int ZEND_FASTCALL  ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op2;
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_CONST != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) {
+        zval *container = opline->op1.zv;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -4874,6 +4934,36 @@ static int ZEND_FASTCALL  ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
        return zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op2;
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_CONST != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) {
+        zval *container = opline->op1.zv;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -6104,6 +6194,36 @@ static int ZEND_FASTCALL  ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_CONST != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_CONST == IS_TMP_VAR || IS_CONST == IS_CONST) {
+        zval *container = opline->op1.zv;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -7840,6 +7960,36 @@ static int ZEND_FASTCALL  ZEND_FETCH_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
        return zend_fetch_var_address_helper_SPEC_TMP_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_TMP_VAR != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+        zval_dtor(free_op1.var);
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -8534,6 +8684,36 @@ static int ZEND_FASTCALL  ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1, free_op2;
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_TMP_VAR != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+        zval_dtor(free_op1.var);
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -9208,6 +9388,36 @@ static int ZEND_FASTCALL  ZEND_FETCH_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
        return zend_fetch_var_address_helper_SPEC_TMP_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1, free_op2;
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_TMP_VAR != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+        zval_dtor(free_op1.var);
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -10304,6 +10514,36 @@ static int ZEND_FASTCALL  ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+       zend_free_op free_op1;
+       zval **container;
+
+       SAVE_OPLINE();
+
+       if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) &&
+           IS_TMP_VAR != IS_CV &&
+           EX_T(opline->op1.var).var.ptr_ptr) {
+               PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
+       }
+
+    if (IS_TMP_VAR == IS_TMP_VAR || IS_TMP_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+        zval_dtor(free_op1.var);
+    } else {
+        container = NULL;
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+
+    }
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -12858,10 +13098,19 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
 
-       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    } else {
+        container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    }
+
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
@@ -15025,10 +15274,19 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
-       zval_dtor(free_op2.var);
-       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+    if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    } else {
+        container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    }
+
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
@@ -17106,10 +17364,19 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
-       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
-       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+    if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    } else {
+        container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    }
+
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
@@ -20222,10 +20489,19 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
 
-       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    if (IS_VAR == IS_TMP_VAR || IS_VAR == IS_CONST) {
+        zval *container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    } else {
+        container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+    }
+
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
@@ -28655,10 +28931,19 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+    if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) {
+        zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+
+    } else {
+        container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
 
 
+    }
+
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
 }
@@ -30601,9 +30886,18 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
-       zval_dtor(free_op2.var);
+
+    if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) {
+        zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+
+    } else {
+        container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+        zval_dtor(free_op2.var);
+
+    }
 
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -32553,9 +32847,18 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
-       if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+    if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) {
+        zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+    } else {
+        container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+        if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+    }
 
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -35400,9 +35703,18 @@ static int ZEND_FASTCALL  ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
            EX_T(opline->op1.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
        }
-       container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
-       zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
 
+    if (IS_CV == IS_TMP_VAR || IS_CV == IS_CONST) {
+        zval *container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), &container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+
+    } else {
+        container = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+        zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+
+    }
 
        CHECK_EXCEPTION();
        ZEND_VM_NEXT_OPCODE();
@@ -38520,16 +38832,16 @@ void zend_init_opcodes_handlers(void)
        ZEND_FETCH_R_SPEC_CV_VAR_HANDLER,
        ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER,
        ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER,
        ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER,
        ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER,
        ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER,
        ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER,
        ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER,