summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2009-03-18 12:53:17 +0000
committerDmitry Stogov <dmitry@php.net>2009-03-18 12:53:17 +0000
commitff5620524c943828426b8ba7eda337d1d9093ddd (patch)
tree1b0c64cab2a4800d7a011564bb4b95e7529c7a8b
parent15de25b22864d218b00021702bef8b5489936e04 (diff)
downloadphp-git-ff5620524c943828426b8ba7eda337d1d9093ddd.tar.gz
Fixed bug #47704 (crashes on some "bad" operations with string offsets)
Removed unnecessary checks
-rw-r--r--Zend/tests/bug47704.phpt9
-rw-r--r--Zend/zend_execute.c24
-rw-r--r--Zend/zend_vm_def.h116
-rw-r--r--Zend/zend_vm_execute.h1412
4 files changed, 622 insertions, 939 deletions
diff --git a/Zend/tests/bug47704.phpt b/Zend/tests/bug47704.phpt
new file mode 100644
index 0000000000..151754a4f9
--- /dev/null
+++ b/Zend/tests/bug47704.phpt
@@ -0,0 +1,9 @@
+--TEST--
+Bug #47704 (crashes on some "bad" operations with string offsets)
+--FILE--
+<?php
+$s = "abd";
+$s[0]->a += 1;
+?>
+--EXPECTF--
+Fatal error: Cannot use string offset as an object in %sbug47704.php on line %d
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index a752f331a2..f7feff43b0 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -861,17 +861,8 @@ num_index:
default:
zend_error(E_WARNING, "Illegal offset type");
- switch (type) {
- case BP_VAR_R:
- case BP_VAR_IS:
- case BP_VAR_UNSET:
- retval = &EG(uninitialized_zval_ptr);
- break;
- default:
- retval = &EG(error_zval_ptr);
- break;
- }
- break;
+ return (type == BP_VAR_W || type == BP_VAR_RW) ?
+ &EG(error_zval_ptr) : &EG(uninitialized_zval_ptr);
}
return retval;
}
@@ -1048,12 +1039,7 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont
break;
case IS_NULL:
- if (container == EG(error_zval_ptr)) {
- if (result) {
- AI_SET_PTR(result->var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- } else if (result) {
+ if (result) {
AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
}
@@ -1119,8 +1105,8 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval **cont
zval_ptr_dtor(&overloaded_result);
}
} else if (result) {
- AI_SET_PTR(result->var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
+ AI_SET_PTR(result->var, EG(uninitialized_zval_ptr));
+ PZVAL_LOCK(EG(uninitialized_zval_ptr));
}
if (dim_is_tmp_var) {
zval_ptr_dtor(&dim);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 6c37ca5e19..9a970b8749 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -303,6 +303,10 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (OP1_TYPE == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -343,17 +347,14 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -369,13 +370,10 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -413,33 +411,29 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W);
-
- if (object_ptr && OP1_TYPE != IS_CV && !OP1_FREE) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (OP1_TYPE == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (OP1_TYPE == IS_VAR && !OP1_FREE) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_obj_helper, binary_op, binary_op);
} else {
zend_op *op_data = opline+1;
zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
- zval **container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
- if (OP1_TYPE == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -461,9 +455,6 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
}
FREE_OP2();
FREE_OP1_VAR_PTR();
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -487,8 +478,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
}
FREE_OP2();
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -561,6 +551,10 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (OP1_TYPE == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -654,6 +648,10 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (OP1_TYPE == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -745,7 +743,7 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (OP1_TYPE == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
@@ -786,7 +784,7 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (OP1_TYPE == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
@@ -827,7 +825,7 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (OP1_TYPE == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
}
@@ -865,7 +863,7 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
if (OP1_TYPE == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (OP1_TYPE == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
}
@@ -1239,17 +1237,6 @@ ZEND_VM_HELPER_EX(zend_fetch_property_address_read_helper, VAR|UNUSED|CV, CONST|
zend_free_op free_op2;
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- FREE_OP2();
- FREE_OP1();
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -1510,16 +1497,12 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
zend_free_op free_op1;
- zval **object_ptr;
+ zval **object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
- if (OP1_TYPE == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
- } else {
- object_ptr = NULL;
+ if (OP1_TYPE == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
zval *property_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
@@ -1538,9 +1521,6 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
zval **variable_ptr_ptr;
- if (OP1_TYPE == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
FREE_OP2();
@@ -1581,7 +1561,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
zval *value = GET_OP2_ZVAL_PTR(BP_VAR_R);
zval **variable_ptr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
- if (!variable_ptr_ptr) {
+ if (OP1_TYPE == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, OP2_TYPE TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -2915,10 +2895,6 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
- FREE_OP1_IF_VAR();
- ZEND_VM_NEXT_OPCODE();
}
ce = Z_OBJCE_P(obj);
@@ -2930,8 +2906,6 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
} else {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
}
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
}
if (ce && clone) {
@@ -3394,7 +3368,7 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
long index;
- if (container) {
+ if (OP1_TYPE != IS_VAR || container) {
if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -3487,7 +3461,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
zval **container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET);
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (container) {
+ if (OP1_TYPE != IS_VAR || container) {
if (OP1_TYPE == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -3893,7 +3867,7 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
int result = 0;
long index;
- if (container) {
+ if (OP1_TYPE != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 2b4f9e7a7b..440a31ab59 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1712,10 +1712,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
-
- ZEND_VM_NEXT_OPCODE();
}
ce = Z_OBJCE_P(obj);
@@ -1727,8 +1723,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
} else {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
}
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
}
if (ce && clone) {
@@ -4941,10 +4935,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
-
- ZEND_VM_NEXT_OPCODE();
}
ce = Z_OBJCE_P(obj);
@@ -4956,8 +4946,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
}
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
}
if (ce && clone) {
@@ -7597,7 +7585,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (IS_VAR == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_VAR == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
@@ -7638,7 +7626,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (IS_VAR == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_VAR == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
@@ -7679,7 +7667,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (IS_VAR == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_VAR == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
}
@@ -7717,7 +7705,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (IS_VAR == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_VAR == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
}
@@ -8265,10 +8253,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
- if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- ZEND_VM_NEXT_OPCODE();
}
ce = Z_OBJCE_P(obj);
@@ -8280,8 +8264,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
}
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
}
if (ce && clone) {
@@ -9279,6 +9261,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -9319,17 +9305,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -9345,13 +9328,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -9389,33 +9369,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
zend_free_op free_op1, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
-
- if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = &opline->op2.u.constant;
- zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -9437,9 +9413,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -9462,8 +9435,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -9536,6 +9508,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -9629,6 +9605,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -9895,17 +9875,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST(
zval *offset = &opline->op2.u.constant;
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
-
- if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -10144,16 +10113,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
zend_free_op free_op1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zval *property_name = &opline->op2.u.constant;
@@ -10172,9 +10137,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zval *dim = &opline->op2.u.constant;
zval **variable_ptr_ptr;
- if (IS_VAR == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -10214,7 +10176,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
zval *value = &opline->op2.u.constant;
zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_VAR == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -10588,7 +10550,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
zval *offset = &opline->op2.u.constant;
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -10681,7 +10643,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
zval *offset = &opline->op2.u.constant;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -10719,7 +10681,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
int result = 0;
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
zval *offset = &opline->op2.u.constant;
@@ -11112,6 +11074,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -11152,17 +11118,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -11178,13 +11141,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -11222,33 +11182,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
-
- if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -11270,9 +11226,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
}
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -11296,8 +11249,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
}
zval_dtor(free_op2.var);
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -11370,6 +11322,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -11463,6 +11419,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -11729,17 +11689,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(in
zend_free_op free_op2;
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- zval_dtor(free_op2.var);
- if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -11978,16 +11927,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
zend_free_op free_op1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -12006,9 +11951,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
- if (IS_VAR == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
@@ -12049,7 +11991,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
zval *value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_VAR == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -12368,7 +12310,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -12461,7 +12403,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -12499,7 +12441,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
int result = 0;
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -12892,6 +12834,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -12932,17 +12878,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -12958,13 +12901,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -13002,33 +12942,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
-
- if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -13050,9 +12986,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -13076,8 +13009,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -13150,6 +13082,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -13243,6 +13179,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -13509,17 +13449,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(in
zend_free_op free_op2;
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -13758,16 +13687,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
zend_free_op free_op1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -13786,9 +13711,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
- if (IS_VAR == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -13829,7 +13751,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_VAR == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -14199,7 +14121,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -14292,7 +14214,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -14330,7 +14252,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
int result = 0;
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -14479,6 +14401,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -14519,17 +14445,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -14545,13 +14468,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -14589,33 +14509,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
zend_free_op free_op1, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
-
- if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = NULL;
- zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -14637,9 +14553,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -14662,8 +14575,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -14823,16 +14735,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
zend_free_op free_op1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zval *property_name = NULL;
@@ -14851,9 +14759,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zval *dim = NULL;
zval **variable_ptr_ptr;
- if (IS_VAR == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -15334,6 +15239,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -15374,17 +15283,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -15400,13 +15306,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -15444,33 +15347,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
zend_free_op free_op1, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
-
- if (object_ptr && IS_VAR != IS_CV && !(free_op1.var != NULL)) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -15492,9 +15391,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -15517,8 +15413,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -15591,6 +15486,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -15684,6 +15583,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -15950,17 +15853,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(int
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
-
- if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -16199,16 +16091,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
zend_free_op free_op1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (IS_VAR == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_VAR == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
@@ -16227,9 +16115,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
zval **variable_ptr_ptr;
- if (IS_VAR == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -16269,7 +16154,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
zval **variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_VAR == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -16635,7 +16520,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -16728,7 +16613,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -16766,7 +16651,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
int result = 0;
long index;
- if (container) {
+ if (IS_VAR != IS_VAR || container) {
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
@@ -16914,10 +16799,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
-
- ZEND_VM_NEXT_OPCODE();
}
ce = Z_OBJCE_P(obj);
@@ -16929,8 +16810,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG
} else {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
}
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
}
if (ce && clone) {
@@ -16996,6 +16875,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -17036,17 +16919,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -17062,13 +16942,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -17105,33 +16982,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
zend_free_op free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-
- if (object_ptr && IS_UNUSED != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = &opline->op2.u.constant;
- zval **container = NULL;
- if (IS_UNUSED == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -17153,9 +17026,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -17178,8 +17048,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -17252,6 +17121,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -17345,6 +17218,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -17435,17 +17312,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CON
zval *offset = &opline->op2.u.constant;
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
-
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -17853,7 +17719,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H
zval *offset = &opline->op2.u.constant;
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -17945,7 +17811,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H
zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *offset = &opline->op2.u.constant;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -17982,7 +17848,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
int result = 0;
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
zval *offset = &opline->op2.u.constant;
@@ -18129,6 +17995,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -18169,17 +18039,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -18195,13 +18062,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -18238,33 +18102,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
zend_free_op free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-
- if (object_ptr && IS_UNUSED != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- zval **container = NULL;
- if (IS_UNUSED == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -18286,9 +18146,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
}
zval_dtor(free_op2.var);
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -18312,8 +18169,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
}
zval_dtor(free_op2.var);
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -18386,6 +18242,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -18479,6 +18339,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -18569,17 +18433,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP
zend_free_op free_op2;
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- zval_dtor(free_op2.var);
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -18932,7 +18785,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -19024,7 +18877,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -19061,7 +18914,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
int result = 0;
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -19208,6 +19061,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -19248,17 +19105,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -19274,13 +19128,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -19317,33 +19168,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
zend_free_op free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-
- if (object_ptr && IS_UNUSED != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- zval **container = NULL;
- if (IS_UNUSED == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -19365,9 +19212,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -19391,8 +19235,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -19465,6 +19308,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -19558,6 +19405,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -19648,17 +19499,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR
zend_free_op free_op2;
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -20011,7 +19851,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -20103,7 +19943,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -20140,7 +19980,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
int result = 0;
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -20287,6 +20127,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -20327,17 +20171,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -20353,13 +20194,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -20396,33 +20234,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
zend_free_op free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-
- if (object_ptr && IS_UNUSED != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = NULL;
- zval **container = NULL;
- if (IS_UNUSED == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -20444,9 +20278,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -20469,8 +20300,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -20559,6 +20389,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -20599,17 +20433,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -20625,13 +20456,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -20668,33 +20496,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
zend_free_op free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
-
- if (object_ptr && IS_UNUSED != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_UNUSED == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- zval **container = NULL;
- if (IS_UNUSED == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -20716,9 +20540,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -20741,8 +20562,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -20815,6 +20635,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -20908,6 +20732,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_UNUSED == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -20998,17 +20826,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
-
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -21359,7 +21176,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -21451,7 +21268,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -21488,7 +21305,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
int result = 0;
long index;
- if (container) {
+ if (IS_UNUSED != IS_VAR || container) {
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
@@ -21654,7 +21471,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (IS_CV == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_CV == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
@@ -21694,7 +21511,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (IS_CV == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_CV == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
AI_SET_PTR(EX_T(opline->result.u.var).var, EG(uninitialized_zval_ptr));
PZVAL_LOCK(EG(uninitialized_zval_ptr));
@@ -21734,7 +21551,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (IS_CV == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_CV == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
}
@@ -21771,7 +21588,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (IS_CV == IS_VAR && !var_ptr) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
}
- if (*var_ptr == EG(error_zval_ptr)) {
+ if (IS_CV == IS_VAR && *var_ptr == EG(error_zval_ptr)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).tmp_var = *EG(uninitialized_zval_ptr);
}
@@ -22301,10 +22118,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
if (!obj || Z_TYPE_P(obj) != IS_OBJECT) {
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
-
- ZEND_VM_NEXT_OPCODE();
}
ce = Z_OBJCE_P(obj);
@@ -22316,8 +22129,6 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else {
zend_error_noreturn(E_ERROR, "Trying to clone an uncloneable object");
}
- EX_T(opline->result.u.var).var.ptr = EG(error_zval_ptr);
- Z_ADDREF_P(EX_T(opline->result.u.var).var.ptr);
}
if (ce && clone) {
@@ -23168,6 +22979,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -23208,17 +23023,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -23234,13 +23046,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -23277,33 +23086,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
zend_free_op free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (object_ptr && IS_CV != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = &opline->op2.u.constant;
- zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (IS_CV == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -23325,9 +23130,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -23350,8 +23152,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -23424,6 +23225,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -23517,6 +23322,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -23782,17 +23591,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CONST(i
zval *offset = &opline->op2.u.constant;
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
-
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -24028,16 +23826,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zval *property_name = &opline->op2.u.constant;
@@ -24056,9 +23850,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zval *dim = &opline->op2.u.constant;
zval **variable_ptr_ptr;
- if (IS_CV == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -24098,7 +23889,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
zval *value = &opline->op2.u.constant;
zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_CV == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CONST TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -24315,7 +24106,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
zval *offset = &opline->op2.u.constant;
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -24407,7 +24198,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
zval *offset = &opline->op2.u.constant;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -24444,7 +24235,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
int result = 0;
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
zval *offset = &opline->op2.u.constant;
@@ -24835,6 +24626,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -24875,17 +24670,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -24901,13 +24693,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -24944,33 +24733,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
zend_free_op free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
-
- if (object_ptr && IS_CV != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (IS_CV == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -24992,9 +24777,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
}
zval_dtor(free_op2.var);
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -25018,8 +24800,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
}
zval_dtor(free_op2.var);
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -25092,6 +24873,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -25185,6 +24970,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -25450,17 +25239,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_TMP(int
zend_free_op free_op2;
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- zval_dtor(free_op2.var);
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -25696,16 +25474,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -25724,9 +25498,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
- if (IS_CV == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
@@ -25767,7 +25538,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_CV == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_TMP_VAR TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -25986,7 +25757,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -26078,7 +25849,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -26115,7 +25886,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
int result = 0;
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -26506,6 +26277,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -26546,17 +26321,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -26572,13 +26344,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -26615,33 +26384,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
zend_free_op free_op2, free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (object_ptr && IS_CV != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (IS_CV == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -26663,9 +26428,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -26689,8 +26451,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -26763,6 +26524,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -26856,6 +26621,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -27121,17 +26890,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(int
zend_free_op free_op2;
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
- if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -27367,16 +27125,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -27395,9 +27149,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
- if (IS_CV == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -27438,7 +27189,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_CV == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_VAR TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -27707,7 +27458,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -27799,7 +27550,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -27836,7 +27587,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int
int result = 0;
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
zend_free_op free_op2;
zval *offset = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC);
@@ -27983,6 +27734,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -28023,17 +27778,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -28049,13 +27801,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -28092,33 +27841,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
zend_free_op free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
-
- if (object_ptr && IS_CV != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = NULL;
- zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (IS_CV == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -28140,9 +27885,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -28165,8 +27907,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -28325,16 +28066,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zval *property_name = NULL;
@@ -28353,9 +28090,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zval *dim = NULL;
zval **variable_ptr_ptr;
- if (IS_CV == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -28739,6 +28473,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
znode *result = &opline->result;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
+ }
+
EX_T(result->u.var).var.ptr_ptr = NULL;
make_real_object(object_ptr TSRMLS_CC);
object = *object_ptr;
@@ -28779,17 +28517,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
if (!have_get_ptr) {
zval *z = NULL;
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- if (Z_OBJ_HT_P(object)->read_property) {
- z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
- case ZEND_ASSIGN_DIM:
- if (Z_OBJ_HT_P(object)->read_dimension) {
- z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
- }
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ if (Z_OBJ_HT_P(object)->read_property) {
+ z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R TSRMLS_CC);
+ }
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ if (Z_OBJ_HT_P(object)->read_dimension) {
+ z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R TSRMLS_CC);
+ }
}
if (z) {
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
@@ -28805,13 +28540,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
Z_ADDREF_P(z);
SEPARATE_ZVAL_IF_NOT_REF(&z);
binary_op(z, z, value TSRMLS_CC);
- switch (opline->extended_value) {
- case ZEND_ASSIGN_OBJ:
- Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
- break;
- case ZEND_ASSIGN_DIM:
- Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
- break;
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ Z_OBJ_HT_P(object)->write_property(object, property, z TSRMLS_CC);
+ } else /* if (opline->extended_value == ZEND_ASSIGN_DIM) */ {
+ Z_OBJ_HT_P(object)->write_dimension(object, property, z TSRMLS_CC);
}
if (!RETURN_VALUE_UNUSED(result)) {
EX_T(result->u.var).var.ptr = z;
@@ -28848,33 +28580,29 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
zend_free_op free_op_data2, free_op_data1;
zval **var_ptr;
zval *value;
- zend_bool increment_opline = 0;
switch (opline->extended_value) {
case ZEND_ASSIGN_OBJ:
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
-
- if (object_ptr && IS_CV != IS_CV && !0) {
- Z_ADDREF_PP(object_ptr); /* undo the effect of get_obj_zval_ptr_ptr() */
- }
+ zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !container) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
+ } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ if (IS_CV == IS_VAR && !0) {
+ Z_ADDREF_PP(container); /* undo the effect of get_obj_zval_ptr_ptr() */
+ }
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
zend_op *op_data = opline+1;
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC);
- if (IS_CV == IS_VAR && !container) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC);
- increment_opline = 1;
+ ZEND_VM_INC_OPCODE();
}
}
break;
@@ -28896,9 +28624,6 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
- }
ZEND_VM_NEXT_OPCODE();
}
@@ -28921,8 +28646,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
PZVAL_LOCK(*var_ptr);
}
- if (increment_opline) {
- ZEND_VM_INC_OPCODE();
+ if (opline->extended_value == ZEND_ASSIGN_DIM) {
FREE_OP(free_op_data1);
FREE_OP_VAR_PTR(free_op_data2);
}
@@ -28995,6 +28719,10 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
zval **retval = &EX_T(opline->result.u.var).var.ptr;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -29088,6 +28816,10 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
zval *retval = &EX_T(opline->result.u.var).tmp_var;
int have_get_ptr = 0;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
+ }
+
make_real_object(object_ptr TSRMLS_CC); /* this should modify object only if it's empty */
object = *object_ptr;
@@ -29353,17 +29085,6 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CV(int
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (container == EG(error_zval_ptr)) {
- if (!RETURN_VALUE_UNUSED(&opline->result)) {
- AI_SET_PTR(EX_T(opline->result.u.var).var, EG(error_zval_ptr));
- PZVAL_LOCK(EG(error_zval_ptr));
- }
-
-
- ZEND_VM_NEXT_OPCODE();
- }
-
-
if (Z_TYPE_P(container) != IS_OBJECT || !Z_OBJ_HT_P(container)->read_property) {
if (type != BP_VAR_IS) {
zend_error(E_NOTICE, "Trying to get property of non-object");
@@ -29599,16 +29320,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_op *opline = EX(opline);
zend_op *op_data = opline+1;
- zval **object_ptr;
+ zval **object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (IS_CV == IS_CV || EX_T(opline->op1.u.var).var.ptr_ptr) {
- /* not an array offset */
- object_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- } else {
- object_ptr = NULL;
+ if (IS_CV == IS_VAR && !object_ptr) {
+ zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
-
- if (object_ptr && Z_TYPE_PP(object_ptr) == IS_OBJECT) {
+ if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zval *property_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
@@ -29627,9 +29344,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
zval **variable_ptr_ptr;
- if (IS_CV == IS_VAR && !object_ptr) {
- zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- }
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC);
value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R);
@@ -29669,7 +29383,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *value = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
zval **variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC);
- if (!variable_ptr_ptr) {
+ if (IS_CV == IS_VAR && !variable_ptr_ptr) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.u.var), value, IS_CV TSRMLS_CC)) {
if (!RETURN_VALUE_UNUSED(&opline->result)) {
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
@@ -29934,7 +29648,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -30026,7 +29740,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_UNSET TSRMLS_CC);
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);
- if (container) {
+ if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -30063,7 +29777,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int
int result = 0;
long index;
- if (container) {
+ if (IS_CV != IS_VAR || container) {
zval *offset = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC);