summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2014-10-21 19:30:43 +0400
committerDmitry Stogov <dmitry@zend.com>2014-10-21 19:30:43 +0400
commitfe8577efb1ecf845b937e877634f10ad95b08b75 (patch)
tree9b20b12079401bcf7cccb0f89983ea5a01e04eed /Zend
parent33645f4f553cff6fe8764064e6d9b5ca8bc5b4e1 (diff)
downloadphp-git-fe8577efb1ecf845b937e877634f10ad95b08b75.tar.gz
Optimized ASSIGN_DIM and related opcodes
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_compile.c4
-rw-r--r--Zend/zend_execute.c117
-rw-r--r--Zend/zend_vm_def.h41
-rw-r--r--Zend/zend_vm_execute.h486
4 files changed, 408 insertions, 240 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 5d3ee24c84..a8bfdb1a40 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2281,8 +2281,6 @@ void zend_compile_assign(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
opline->opcode = ZEND_ASSIGN_DIM;
opline = zend_emit_op_data(&expr_node TSRMLS_CC);
- opline->op2.var = get_temporary_variable(CG(active_op_array));
- opline->op2_type = IS_VAR;
return;
case ZEND_AST_PROP:
offset = zend_delayed_compile_begin(TSRMLS_C);
@@ -2374,8 +2372,6 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast TSRMLS_DC) /* {{{
opline->extended_value = ZEND_ASSIGN_DIM;
opline = zend_emit_op_data(&expr_node TSRMLS_CC);
- opline->op2.var = get_temporary_variable(CG(active_op_array));
- opline->op2_type = IS_VAR;
return;
case ZEND_AST_PROP:
offset = zend_delayed_compile_begin(TSRMLS_C);
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 58038c94a4..7c6deca6c8 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1048,12 +1048,61 @@ str_index:
return retval;
}
-static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval *container_ptr, zval *dim, int dim_type, int type, int is_ref, int allow_str_offset TSRMLS_DC)
+static zend_never_inline zend_long zend_check_string_offset(zval *container, zval *dim, int type TSRMLS_DC)
+{
+ zend_long offset;
+
+ if (dim == NULL) {
+ zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
+ }
+
+ if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
+ 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 (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_FALSE:
+ case IS_TRUE:
+ zend_error(E_NOTICE, "String offset cast occurred");
+ break;
+ default:
+ zend_error(E_WARNING, "Illegal offset type");
+ break;
+ }
+
+ offset = zval_get_long(dim);
+ } else {
+ offset = Z_LVAL_P(dim);
+ }
+
+ return offset;
+}
+
+static zend_always_inline zend_long zend_fetch_string_offset(zval *container, zval *dim, int type TSRMLS_DC)
+{
+ zend_long offset = zend_check_string_offset(container, dim, type TSRMLS_CC);
+
+ if (Z_REFCOUNTED_P(container)) {
+ if (Z_REFCOUNT_P(container) > 1) {
+ Z_DELREF_P(container);
+ zval_copy_ctor_func(container);
+ }
+ Z_ADDREF_P(container);
+ }
+ return offset;
+}
+
+static zend_always_inline void zend_fetch_dimension_address(zval *result, zval *container, zval *dim, int dim_type, int type, int is_ref TSRMLS_DC)
{
zval *retval;
- zval *container = container_ptr;
- ZVAL_DEREF(container);
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
SEPARATE_ARRAY(container);
fetch_from_array:
@@ -1071,8 +1120,6 @@ fetch_from_array:
}
ZVAL_INDIRECT(result, retval);
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
- zend_long offset;
-
if (type != BP_VAR_UNSET && UNEXPECTED(Z_STRLEN_P(container) == 0)) {
zval_ptr_dtor_nogc(container);
convert_to_array:
@@ -1081,49 +1128,9 @@ convert_to_array:
goto fetch_from_array;
}
- if (dim == NULL) {
- zend_error_noreturn(E_ERROR, "[] operator not supported for strings");
- }
-
- if (UNEXPECTED(Z_TYPE_P(dim) != IS_LONG)) {
- 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 (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_FALSE:
- case IS_TRUE:
- zend_error(E_NOTICE, "String offset cast occurred");
- break;
- default:
- zend_error(E_WARNING, "Illegal offset type");
- break;
- }
-
- offset = zval_get_long(dim);
- } else {
- offset = Z_LVAL_P(dim);
- }
-
- if (allow_str_offset) {
- if (Z_REFCOUNTED_P(container)) {
- if (Z_REFCOUNT_P(container) > 1) {
- Z_DELREF_P(container);
- zval_copy_ctor_func(container);
- }
- Z_ADDREF_P(container);
- }
- ZVAL_LONG(result, offset);
- return container; /* assignment to string offset */
- } else {
- ZVAL_INDIRECT(result, NULL); /* wrong string offset */
- }
+ zend_check_string_offset(container, dim, type TSRMLS_CC);
+
+ ZVAL_INDIRECT(result, NULL); /* wrong string offset */
} 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");
@@ -1185,32 +1192,26 @@ convert_to_array:
ZVAL_INDIRECT(result, &EG(error_zval));
}
}
- return NULL; /* not an assignment to string offset */
}
static zend_never_inline void zend_fetch_dimension_address_W(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, 0, 0 TSRMLS_CC);
-}
-
-static zend_never_inline zval *zend_fetch_dimension_address_W_str(zval *result, zval *container_ptr, zval *dim, int dim_type TSRMLS_DC)
-{
- return zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0, 1 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 0 TSRMLS_CC);
}
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, 0 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_W, 1 TSRMLS_CC);
}
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, 0 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_RW, 0 TSRMLS_CC);
}
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, 0 TSRMLS_CC);
+ zend_fetch_dimension_address(result, container_ptr, dim, dim_type, BP_VAR_UNSET, 0 TSRMLS_CC);
}
static zend_always_inline void zend_fetch_dimension_address_read(zval *result, zval *container, zval *dim, int dim_type, int type TSRMLS_DC)
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 0c5ef75be4..f41365b615 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -423,15 +423,19 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV, int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC))
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (OP1_TYPE != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (OP1_TYPE == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (OP1_TYPE == IS_VAR && !OP1_FREE) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -439,9 +443,10 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
} else {
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, OP2_TYPE TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, OP2_TYPE TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -465,7 +470,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_dim_helper, VAR|UNUSED|CV, CONST|TMP|VAR
FREE_OP2();
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
FREE_OP1_VAR_PTR();
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -1195,6 +1199,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, 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");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
} else {
@@ -1221,6 +1226,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, 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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -1262,6 +1268,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNU
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC);
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -1293,6 +1300,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -1549,19 +1557,25 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, OP1_TYPE, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
FREE_OP2();
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, OP2_TYPE TSRMLS_CC);
- FREE_OP2();
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ FREE_OP2();
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, OP2_TYPE TSRMLS_CC);
+ FREE_OP2();
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -1575,7 +1589,6 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 14f2d6ebb5..fe443f87b3 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3931,6 +3931,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5275,6 +5276,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -6469,6 +6471,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7503,6 +7506,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -8386,6 +8390,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(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 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -10734,6 +10739,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -11917,6 +11923,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13084,6 +13091,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14092,6 +14100,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14827,6 +14836,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(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 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -17561,15 +17571,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -17577,9 +17591,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -17602,7 +17617,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -18139,6 +18153,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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 {
@@ -18165,6 +18180,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18206,6 +18222,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18237,6 +18254,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18491,19 +18509,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -18517,7 +18541,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -19949,15 +19972,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -19965,9 +19992,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -19991,7 +20019,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -20380,6 +20407,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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 {
@@ -20406,6 +20434,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20447,6 +20476,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");
}
+ ZVAL_DEREF(container);
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 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20478,6 +20508,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20701,19 +20732,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -20727,7 +20764,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -21921,15 +21957,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -21937,9 +21977,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -21963,7 +22004,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -22503,6 +22543,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
} else {
@@ -22529,6 +22570,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -22570,6 +22612,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22601,6 +22644,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -22824,19 +22868,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -22850,7 +22900,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -23978,15 +24027,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -23994,9 +24047,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -24019,7 +24073,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -24367,6 +24420,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
} else {
@@ -24393,6 +24447,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -24419,6 +24474,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24458,19 +24514,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -24484,7 +24546,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -25409,15 +25470,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -25425,9 +25490,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -25450,7 +25516,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -25836,6 +25901,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(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);
} else {
@@ -25862,6 +25928,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -25903,6 +25970,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(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 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -25934,6 +26002,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -26155,19 +26224,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -26181,7 +26256,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -27236,15 +27310,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -27252,9 +27330,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -27277,7 +27356,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -28587,15 +28665,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -28603,9 +28685,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -28629,7 +28712,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -29857,15 +29939,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -29873,9 +29959,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -29899,7 +29986,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -31126,15 +31212,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31142,9 +31232,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31167,7 +31258,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -31613,15 +31703,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31629,9 +31723,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31654,7 +31749,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -34548,15 +34642,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -34564,9 +34662,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -34589,7 +34688,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -35126,6 +35224,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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 {
@@ -35152,6 +35251,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35193,6 +35293,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35224,6 +35325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35478,19 +35580,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -35504,7 +35612,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -36768,15 +36875,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -36784,9 +36895,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -36810,7 +36922,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -37199,6 +37310,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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 {
@@ -37225,6 +37337,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37266,6 +37379,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");
}
+ ZVAL_DEREF(container);
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 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37297,6 +37411,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
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_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37520,19 +37635,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -37546,7 +37667,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -38612,15 +38732,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -38628,9 +38752,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -38654,7 +38779,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -39194,6 +39318,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
} else {
@@ -39220,6 +39345,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -39261,6 +39387,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39292,6 +39419,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -39515,19 +39643,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -39541,7 +39675,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -40539,15 +40672,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -40555,9 +40692,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -40580,7 +40718,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -40928,6 +41065,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
} else {
@@ -40954,6 +41092,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -40980,6 +41119,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41019,19 +41159,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -41045,7 +41191,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -41825,15 +41970,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -41841,9 +41990,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_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_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((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);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -41866,7 +42016,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
}
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -42252,6 +42401,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
if (EXPECTED(opline->extended_value == 0)) {
zend_fetch_dimension_address_W(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);
} else {
@@ -42278,6 +42428,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -42319,6 +42470,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");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(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 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42350,6 +42502,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(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 && READY_TO_DESTROY(free_op1.var)) {
@@ -42571,19 +42724,25 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -42597,7 +42756,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}