summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-10-05 13:02:58 +0400
committerDmitry Stogov <dmitry@zend.com>2014-10-05 13:02:58 +0400
commit7c7b9184b1fdf7add1715079f22241bc1185fcb0 (patch)
tree2b7db868c156e5b65106c34438f90ed3767c93fb
parent429e1b45a7cd2f491e836f4bffa57c72beb6128b (diff)
downloadphp-git-7c7b9184b1fdf7add1715079f22241bc1185fcb0.tar.gz
Fixed list() behavior inconsistency (string handling is disabled for all cases, ArrayAccess objects handling is enabled for all cases, ZEND_FETCH_DIM_TMP_VAR opcode is renamed into ZEND_FETCH_LIST, ZEND_FETCH_ADD_LOCK flag is removed).
-rw-r--r--Zend/tests/bug39304.phpt4
-rw-r--r--Zend/tests/bug39304_2_4.phpt8
-rw-r--r--Zend/tests/foreach_list_002.phpt8
-rw-r--r--Zend/tests/list_005.phpt6
-rw-r--r--Zend/tests/list_007.phpt5
-rw-r--r--Zend/zend_compile.c37
-rw-r--r--Zend/zend_compile.h1
-rw-r--r--Zend/zend_vm_def.h27
-rw-r--r--Zend/zend_vm_execute.h160
-rw-r--r--Zend/zend_vm_opcodes.c2
-rw-r--r--Zend/zend_vm_opcodes.h2
-rw-r--r--ext/opcache/Optimizer/block_pass.c2
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c2
-rw-r--r--sapi/phpdbg/phpdbg_opcode.c2
14 files changed, 152 insertions, 114 deletions
diff --git a/Zend/tests/bug39304.phpt b/Zend/tests/bug39304.phpt
index 5540135fa4..2e9ebcdee4 100644
--- a/Zend/tests/bug39304.phpt
+++ b/Zend/tests/bug39304.phpt
@@ -8,9 +8,5 @@ echo "I am alive";
?>
--EXPECTF--
Notice: Uninitialized string offset: 0 in %sbug39304.php on line %d
-
-Notice: Uninitialized string offset: 0 in %sbug39304.php on line %d
-
-Notice: Uninitialized string offset: 1 in %sbug39304.php on line %d
I am alive
diff --git a/Zend/tests/bug39304_2_4.phpt b/Zend/tests/bug39304_2_4.phpt
index cc0709b424..917c64e2cd 100644
--- a/Zend/tests/bug39304_2_4.phpt
+++ b/Zend/tests/bug39304_2_4.phpt
@@ -10,9 +10,5 @@ Bug #39304 (Segmentation fault with list unpacking of string offset)
?>
--EXPECTF--
Notice: Uninitialized string offset: 0 in %sbug39304_2_4.php on line %d
-
-Notice: Uninitialized string offset: 0 in %sbug39304_2_4.php on line %d
-
-Notice: Uninitialized string offset: 1 in %sbug39304_2_4.php on line %d
-string(0) ""
-string(0) ""
+NULL
+NULL
diff --git a/Zend/tests/foreach_list_002.phpt b/Zend/tests/foreach_list_002.phpt
index bc17d94268..1a7be521b2 100644
--- a/Zend/tests/foreach_list_002.phpt
+++ b/Zend/tests/foreach_list_002.phpt
@@ -18,9 +18,5 @@ foreach($array as list(, $a)) {
int(1)
int(3)
string(1) "b"
-
-Notice: Uninitialized string offset: 1 in %sforeach_list_002.php on line %d
-string(0) ""
-
-Notice: Uninitialized string offset: 1 in %sforeach_list_002.php on line %d
-string(0) ""
+NULL
+NULL
diff --git a/Zend/tests/list_005.phpt b/Zend/tests/list_005.phpt
index ec5640a60a..a3b0d57434 100644
--- a/Zend/tests/list_005.phpt
+++ b/Zend/tests/list_005.phpt
@@ -35,9 +35,9 @@ var_dump($a, $b, $c);
?>
--EXPECTF--
-string(1) "f"
-string(1) "o"
-string(1) "o"
+NULL
+NULL
+NULL
----
NULL
NULL
diff --git a/Zend/tests/list_007.phpt b/Zend/tests/list_007.phpt
index 35a25bce65..cc712406ec 100644
--- a/Zend/tests/list_007.phpt
+++ b/Zend/tests/list_007.phpt
@@ -8,6 +8,5 @@ list($x, $y) = function() { };
var_dump($x, $y);
?>
---EXPECT--
-NULL
-NULL
+--EXPECTF--
+Fatal error: Cannot use object of type Closure as array in %slist_007.php on line 3
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 91bfbfeebb..0172b19560 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -515,15 +515,17 @@ void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */
}
} else {
while (opline>CG(active_op_array)->opcodes) {
- if (opline->opcode == ZEND_FETCH_DIM_R
- && opline->op1_type == IS_VAR
- && opline->op1.var == op1->u.op.var) {
- /* This should the end of a list() construct
- * Mark its result as unused
- */
- opline->extended_value = ZEND_FETCH_STANDARD;
- break;
- } else if (opline->result_type==IS_VAR
+ if (opline->opcode == ZEND_FETCH_LIST &&
+ opline->op1_type == IS_VAR &&
+ opline->op1.var == op1->u.op.var) {
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+ opline->opcode = ZEND_FREE;
+ SET_NODE(opline->op1, op1);
+ SET_UNUSED(opline->op2);
+ return;
+ }
+ if (opline->result_type==IS_VAR
&& opline->result.var == op1->u.op.var) {
if (opline->opcode == ZEND_NEW) {
opline->result_type |= EXT_TYPE_UNUSED;
@@ -2174,20 +2176,6 @@ void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type TSRMLS
}
/* }}} */
-static inline zend_uchar get_list_fetch_opcode(zend_uchar op_type) /* {{{ */
-{
- switch (op_type) {
- case IS_VAR:
- case IS_CV:
- return ZEND_FETCH_DIM_R;
- case IS_TMP_VAR:
- case IS_CONST:
- return ZEND_FETCH_DIM_TMP_VAR;
- EMPTY_SWITCH_DEFAULT_CASE()
- }
-}
-/* }}} */
-
static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_node TSRMLS_DC) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
@@ -2214,8 +2202,7 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
}
opline = zend_emit_op(&fetch_result,
- get_list_fetch_opcode(expr_node->op_type), expr_node, &dim_node TSRMLS_CC);
- opline->extended_value |= ZEND_FETCH_ADD_LOCK;
+ ZEND_FETCH_LIST, expr_node, &dim_node TSRMLS_CC);
zend_emit_assign_znode(var_ast, &fetch_result TSRMLS_CC);
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 2594495c96..c13184c7d8 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -614,7 +614,6 @@ int zend_add_literal(zend_op_array *op_array, zval *zv TSRMLS_DC);
#define ZEND_FETCH_TYPE_MASK 0x70000000
#define ZEND_FETCH_STANDARD 0x00000000
-#define ZEND_FETCH_ADD_LOCK 0x08000000
#define ZEND_FETCH_MAKE_REF 0x04000000
#define ZEND_ISSET 0x02000000
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index d87b1e496f..61224297b5 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1209,9 +1209,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
container = GET_OP1_ZVAL_PTR(BP_VAR_R);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
FREE_OP2();
- if (OP1_TYPE != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- FREE_OP1();
- }
+ FREE_OP1();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -1506,23 +1504,34 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
ZEND_VM_NEXT_OPCODE();
}
-ZEND_VM_HANDLER(98, ZEND_FETCH_DIM_TMP_VAR, CONST|TMP, CONST)
+ZEND_VM_HANDLER(98, ZEND_FETCH_LIST, CONST|TMP|VAR|CV, CONST)
{
USE_OPLINE
zend_free_op free_op1;
zval *container;
SAVE_OPLINE();
- container = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ container = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);
- if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- } else {
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zend_free_op free_op2;
zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE, BP_VAR_R TSRMLS_CC);
ZVAL_COPY(EX_VAR(opline->result.var), value);
- FREE_OP2();
+ } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
+ zval *result = EX_VAR(opline->result.var);
+ zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), BP_VAR_R, result TSRMLS_CC);
+
+ if (retval) {
+ if (result != retval) {
+ ZVAL_COPY(result, retval);
+ }
+ } else {
+ ZVAL_NULL(result);
+ }
+ } else {
+ ZVAL_NULL(EX_VAR(opline->result.var));
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 543c1c25e6..54d2bb2673 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3902,9 +3902,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_
container = opline->op1.zv;
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)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -4055,7 +4053,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
}
}
-static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -4064,14 +4062,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O
SAVE_OPLINE();
container = opline->op1.zv;
- if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- } else {
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
ZVAL_COPY(EX_VAR(opline->result.var), value);
+ } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
+ zval *result = EX_VAR(opline->result.var);
+ zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, opline->op2.zv, BP_VAR_R, result TSRMLS_CC);
+ if (retval) {
+ if (result != retval) {
+ ZVAL_COPY(result, retval);
+ }
+ } else {
+ ZVAL_NULL(result);
+ }
+ } else {
+ ZVAL_NULL(EX_VAR(opline->result.var));
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5249,9 +5258,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA
container = opline->op1.zv;
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_ptr_dtor_nogc(free_op2.var);
- if (IS_CONST != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -6446,9 +6453,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA
container = opline->op1.zv;
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(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)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -8389,9 +8394,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN
container = opline->op1.zv;
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_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)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -10753,9 +10756,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA
container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 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_ptr_dtor_nogc(free_op1.var);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -10906,7 +10907,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
}
}
-static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1;
@@ -10915,14 +10916,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
- ZVAL_NULL(EX_VAR(opline->result.var));
- } else {
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
ZVAL_COPY(EX_VAR(opline->result.var), value);
+ } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
+ zval *result = EX_VAR(opline->result.var);
+ zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, opline->op2.zv, BP_VAR_R, result TSRMLS_CC);
+ if (retval) {
+ if (result != retval) {
+ ZVAL_COPY(result, retval);
+ }
+ } else {
+ ZVAL_NULL(result);
+ }
+ } else {
+ ZVAL_NULL(EX_VAR(opline->result.var));
}
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -11901,9 +11913,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND
container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 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_ptr_dtor_nogc(free_op2.var);
- if (IS_TMP_VAR != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- zval_ptr_dtor_nogc(free_op1.var);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -13034,9 +13044,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND
container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(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_ptr_dtor_nogc(free_op1.var);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -14763,9 +14771,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL
container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_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_ptr_dtor_nogc(free_op1.var);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -18097,9 +18103,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 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);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -18392,6 +18396,39 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *container;
+
+ SAVE_OPLINE();
+ container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+
+ zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+ } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
+ zval *result = EX_VAR(opline->result.var);
+ zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, opline->op2.zv, BP_VAR_R, result TSRMLS_CC);
+
+ if (retval) {
+ if (result != retval) {
+ ZVAL_COPY(result, retval);
+ }
+ } else {
+ ZVAL_NULL(result);
+ }
+ } else {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -20319,9 +20356,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 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_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);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -22446,9 +22481,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(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);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -25837,9 +25870,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_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);
- }
+ zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -35178,9 +35209,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var 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)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -35473,6 +35502,39 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *container;
+
+ SAVE_OPLINE();
+ container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
+
+ zval *value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+ ZVAL_COPY(EX_VAR(opline->result.var), value);
+ } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT) &&
+ EXPECTED(Z_OBJ_HT_P(container)->read_dimension)) {
+ zval *result = EX_VAR(opline->result.var);
+ zval *retval = Z_OBJ_HT_P(container)->read_dimension(container, opline->op2.zv, BP_VAR_R, result TSRMLS_CC);
+
+ if (retval) {
+ if (result != retval) {
+ ZVAL_COPY(result, retval);
+ }
+ } else {
+ ZVAL_NULL(result);
+ }
+ } else {
+ ZVAL_NULL(EX_VAR(opline->result.var));
+ }
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -37233,9 +37295,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var 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_ptr_dtor_nogc(free_op2.var);
- if (IS_CV != IS_VAR || !(opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -39232,9 +39292,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(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)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -42349,9 +42407,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_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)) {
- }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -45896,18 +45952,17 @@ void zend_init_opcodes_handlers(void)
ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER,
- ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
+ ZEND_FETCH_LIST_SPEC_CONST_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_LIST_SPEC_TMP_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_LIST_SPEC_VAR_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
@@ -45917,6 +45972,7 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_LIST_SPEC_CV_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index d31eb14141..067fd362e6 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -120,7 +120,7 @@ const char *zend_vm_opcodes_map[170] = {
"ZEND_FETCH_UNSET",
"ZEND_FETCH_DIM_UNSET",
"ZEND_FETCH_OBJ_UNSET",
- "ZEND_FETCH_DIM_TMP_VAR",
+ "ZEND_FETCH_LIST",
"ZEND_FETCH_CONSTANT",
"ZEND_GOTO",
"ZEND_EXT_STMT",
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 43aea9ee95..c06fd84ff4 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -119,7 +119,7 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_FETCH_UNSET 95
#define ZEND_FETCH_DIM_UNSET 96
#define ZEND_FETCH_OBJ_UNSET 97
-#define ZEND_FETCH_DIM_TMP_VAR 98
+#define ZEND_FETCH_LIST 98
#define ZEND_FETCH_CONSTANT 99
#define ZEND_GOTO 100
#define ZEND_EXT_STMT 101
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 869bd3ccba..f43802647b 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -616,7 +616,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
VAR_SOURCE(opline->op1)->opcode == ZEND_QM_ASSIGN &&
ZEND_OP1_TYPE(VAR_SOURCE(opline->op1)) == IS_CONST &&
opline->opcode != ZEND_CASE && /* CASE _always_ expects variable */
- opline->opcode != ZEND_FETCH_DIM_TMP_VAR && /* in 5.1, FETCH_DIM_TMP_VAR expects T */
+ opline->opcode != ZEND_FETCH_LIST && /* in 5.1, FETCH_DIM_TMP_VAR expects T */
opline->opcode != ZEND_FE_RESET &&
opline->opcode != ZEND_FREE
) {
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index cd75817e0c..70e58f5695 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -244,7 +244,7 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_FETCH_DIM_IS:
case ZEND_FETCH_DIM_FUNC_ARG:
case ZEND_FETCH_DIM_UNSET:
- case ZEND_FETCH_DIM_TMP_VAR:
+ case ZEND_FETCH_LIST:
check_numeric:
{
zend_ulong index;
diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c
index 125a85fe72..f33b1378bf 100644
--- a/sapi/phpdbg/phpdbg_opcode.c
+++ b/sapi/phpdbg/phpdbg_opcode.c
@@ -280,7 +280,7 @@ const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */
CASE(ZEND_FETCH_UNSET);
CASE(ZEND_FETCH_DIM_UNSET);
CASE(ZEND_FETCH_OBJ_UNSET);
- CASE(ZEND_FETCH_DIM_TMP_VAR);
+ CASE(ZEND_FETCH_LIST);
CASE(ZEND_FETCH_CONSTANT);
CASE(ZEND_GOTO);
CASE(ZEND_EXT_STMT);