summaryrefslogtreecommitdiff
path: root/Zend/zend_vm_execute.h
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_vm_execute.h')
-rw-r--r--Zend/zend_vm_execute.h3299
1 files changed, 1541 insertions, 1758 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 4b58d95618..94466c581b 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -538,7 +538,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *p = ZEND_CALL_ARG(call, 1);
for (i = 0; i < call->num_args; ++i) {
- zend_verify_arg_type(fbc, i + 1, p, 0 TSRMLS_CC);
+ zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC);
p++;
}
if (UNEXPECTED(EG(exception) != NULL)) {
@@ -978,7 +978,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
CHECK_EXCEPTION();
}
@@ -1003,7 +1003,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
do {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param);
param++;
@@ -1023,57 +1023,6 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval object_zval;
- zend_function *constructor;
-
- SAVE_OPLINE();
- if (UNEXPECTED((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
- if (Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_INTERFACE) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else if ((Z_CE_P(EX_VAR(opline->op1.var))->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
- zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- } else {
- zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", Z_CE_P(EX_VAR(opline->op1.var))->name->val);
- }
- }
- object_init_ex(&object_zval, Z_CE_P(EX_VAR(opline->op1.var)));
- constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
-
- if (constructor == NULL) {
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
- } else {
- zval_ptr_dtor(&object_zval);
- }
- ZEND_VM_JMP(opline->op2.jmp_addr);
- } else {
- /* We are not handling overloaded classes right now */
- EX(call) = zend_vm_stack_push_call_frame(
- VM_FRAME_INFO(
- VM_FRAME_NESTED_FUNCTION,
- RETURN_VALUE_USED(opline) ?
- ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
- constructor,
- opline->extended_value,
- Z_CE_P(EX_VAR(opline->op1.var)),
- Z_OBJ(object_zval),
- EX(call) TSRMLS_CC);
-
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
- EX(call)->return_value = EX_VAR(opline->result.var);
- } else {
- EX(call)->return_value = NULL;
- }
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
- }
-}
-
static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -1225,7 +1174,7 @@ static int ZEND_FASTCALL ZEND_ADD_TRAIT_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
} else {
trait = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv),
opline->op2.zv + 1,
- opline->extended_value TSRMLS_CC);
+ ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
if (UNEXPECTED(trait == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1474,7 +1423,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -1713,7 +1662,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
}
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
- zend_verify_arg_type(EX(func), arg_num, param, opline->extended_value TSRMLS_CC);
+ zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC);
}
CHECK_EXCEPTION();
@@ -1772,7 +1721,7 @@ static int ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
iface = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
} else {
- iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_INTERFACE TSRMLS_CC);
if (UNEXPECTED(iface == NULL)) {
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1809,7 +1758,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -1995,7 +1944,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2181,7 +2130,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2220,7 +2169,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
} else {
- Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
+ Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, 0 TSRMLS_CC);
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
}
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
@@ -2662,10 +2611,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_CONST == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_CONST == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -2769,6 +2718,72 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval object_zval;
+ zend_function *constructor;
+ zend_class_entry *ce;
+
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
+ }
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
+ constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
+
+ if (constructor == NULL) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
+ } else {
+ zval_ptr_dtor(&object_zval);
+ }
+ ZEND_VM_JMP(opline->op2.jmp_addr);
+ } else {
+ /* We are not handling overloaded classes right now */
+ EX(call) = zend_vm_stack_push_call_frame(
+ VM_FRAME_INFO(
+ VM_FRAME_NESTED_FUNCTION,
+ RETURN_VALUE_USED(opline) ?
+ ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
+ constructor,
+ opline->extended_value,
+ ce,
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
+
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3840,9 +3855,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -3931,6 +3943,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -4033,7 +4046,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -4324,7 +4337,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -4855,9 +4868,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -5275,6 +5289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5379,7 +5394,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -5898,9 +5913,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -6378,9 +6394,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -6469,6 +6482,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -6573,7 +6587,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7237,9 +7251,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -7442,9 +7457,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -7503,6 +7515,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -7981,9 +7994,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -8386,6 +8400,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -8488,7 +8503,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC
if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -9056,9 +9071,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CONST == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CONST == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -9444,10 +9460,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_TMP_VAR == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -10154,27 +10170,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
- zval_ptr_dtor_nogc(free_op1.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10643,9 +10638,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -10734,6 +10726,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -10836,7 +10829,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -11451,6 +11444,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -11497,9 +11529,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -11917,6 +11950,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -12021,7 +12055,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -12513,9 +12547,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -12993,9 +13028,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -13084,6 +13116,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13188,7 +13221,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -13780,6 +13813,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -13826,9 +13898,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14031,9 +14104,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -14092,6 +14162,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14422,9 +14493,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -14827,6 +14899,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -14929,7 +15002,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -15416,9 +15489,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_TMP_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_TMP_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -15970,10 +16044,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_VAR == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_VAR == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -16243,6 +16317,72 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval object_zval;
+ zend_function *constructor;
+ zend_class_entry *ce;
+
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op1.var));
+ }
+ if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) {
+ if (ce->ce_flags & ZEND_ACC_INTERFACE) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", ce->name->val);
+ } else if ((ce->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", ce->name->val);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", ce->name->val);
+ }
+ }
+ object_init_ex(&object_zval, ce);
+ constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval) TSRMLS_CC);
+
+ if (constructor == NULL) {
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval);
+ } else {
+ zval_ptr_dtor(&object_zval);
+ }
+ ZEND_VM_JMP(opline->op2.jmp_addr);
+ } else {
+ /* We are not handling overloaded classes right now */
+ EX(call) = zend_vm_stack_push_call_frame(
+ VM_FRAME_INFO(
+ VM_FRAME_NESTED_FUNCTION,
+ RETURN_VALUE_USED(opline) ?
+ ZEND_CALL_CTOR : (ZEND_CALL_CTOR | ZEND_CALL_CTOR_RESULT_UNUSED)),
+ constructor,
+ opline->extended_value,
+ ce,
+ Z_OBJ(object_zval),
+ EX(call) TSRMLS_CC);
+
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
+ EX(call)->return_value = EX_VAR(opline->result.var);
+ } else {
+ EX(call)->return_value = NULL;
+ }
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -17082,27 +17222,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zend_free_op free_op1;
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
- zval_ptr_dtor_nogc(free_op1.var);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -17472,7 +17591,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -17495,21 +17614,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -17565,15 +17680,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -17581,9 +17700,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -17594,33 +17714,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -17646,31 +17751,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -17826,7 +17917,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -17854,21 +17945,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -17920,7 +18007,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -17946,19 +18033,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -18107,9 +18190,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -18179,11 +18259,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18205,6 +18282,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18246,6 +18324,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18277,6 +18356,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -18334,7 +18414,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18358,7 +18438,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18419,7 +18499,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18445,7 +18525,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -18523,29 +18603,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = opline->op2.zv;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -18559,7 +18643,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -18902,7 +18985,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -19468,6 +19551,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -19514,9 +19636,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -19901,7 +20024,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -19924,21 +20047,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -19995,15 +20114,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -20011,9 +20134,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -20024,33 +20148,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -20076,30 +20186,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
@@ -20256,7 +20353,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -20284,21 +20381,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -20351,7 +20444,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -20377,19 +20470,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -20460,11 +20549,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20486,6 +20572,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20527,6 +20614,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20558,6 +20646,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -20616,7 +20705,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20640,7 +20729,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20702,7 +20791,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20728,7 +20817,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -20773,29 +20862,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -20809,7 +20902,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -21526,9 +21618,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -21913,7 +22006,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -21936,21 +22029,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -22007,15 +22096,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -22023,9 +22116,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -22036,33 +22130,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -22088,30 +22168,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
@@ -22268,7 +22335,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -22296,21 +22363,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -22363,7 +22426,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -22389,19 +22452,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -22551,9 +22610,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -22623,11 +22679,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22649,6 +22702,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -22690,6 +22744,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22721,6 +22776,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -22779,7 +22835,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22803,7 +22859,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22865,7 +22921,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22891,7 +22947,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -22936,29 +22992,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -22972,7 +23032,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -23026,10 +23085,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!(free_op2.var != NULL)) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -23046,15 +23108,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
}
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -23853,6 +23914,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+ zval_ptr_dtor_nogc(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -23899,9 +23999,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -24011,7 +24112,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -24034,21 +24135,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -24104,15 +24201,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -24120,9 +24221,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -24133,33 +24235,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -24185,31 +24272,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -24464,9 +24537,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -24521,11 +24591,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24547,6 +24614,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -24573,6 +24641,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -24604,29 +24673,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = NULL;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -24640,7 +24713,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -25104,9 +25176,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -25476,7 +25549,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -25499,21 +25572,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -25569,15 +25638,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op1, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op1, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_VAR != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -25585,9 +25658,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -25598,33 +25672,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -25650,31 +25709,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -25830,7 +25875,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -25858,21 +25903,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -25924,7 +25965,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
@@ -25950,19 +25991,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -26032,11 +26069,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26058,6 +26092,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -26099,6 +26134,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26130,6 +26166,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -26187,7 +26224,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26211,7 +26248,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26272,7 +26309,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26298,7 +26335,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -26343,29 +26380,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -26379,7 +26420,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -26432,10 +26472,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!0) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -26452,15 +26495,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
}
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -27154,9 +27196,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_VAR == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_VAR == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -27346,7 +27389,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -27369,21 +27412,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -27438,15 +27477,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -27454,9 +27497,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -27467,33 +27511,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -27519,31 +27548,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -27699,7 +27714,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -27727,21 +27742,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -27793,7 +27804,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -27819,19 +27830,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -27921,7 +27928,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -27945,7 +27952,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28006,7 +28013,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28032,7 +28039,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -28262,7 +28269,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
} else {
- ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, opline->extended_value TSRMLS_CC);
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
@@ -28640,9 +28647,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -28736,7 +28744,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -28759,21 +28767,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -28829,15 +28833,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -28845,9 +28853,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -28858,33 +28867,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -28910,30 +28905,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -29090,7 +29072,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -29118,21 +29100,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -29185,7 +29163,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -29211,19 +29189,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -29315,7 +29289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29339,7 +29313,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29401,7 +29375,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29427,7 +29401,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -29948,9 +29922,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -30044,7 +30019,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -30067,21 +30042,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -30137,15 +30108,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -30153,9 +30128,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -30166,33 +30142,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (*
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -30218,30 +30180,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -30398,7 +30347,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -30426,21 +30375,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -30493,7 +30438,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -30519,19 +30464,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -30623,7 +30564,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30647,7 +30588,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30709,7 +30650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -30735,7 +30676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -31256,9 +31197,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -31352,7 +31294,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -31375,21 +31317,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -31444,15 +31382,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31460,9 +31402,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31473,33 +31416,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -31525,31 +31453,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -31775,9 +31689,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -31871,7 +31786,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -31894,21 +31809,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -31963,15 +31874,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_UNUSED != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_UNUSED == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_UNUSED == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -31979,9 +31894,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -31992,33 +31908,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -32044,31 +31945,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -32224,7 +32111,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -32252,21 +32139,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -32318,7 +32201,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC);
@@ -32344,19 +32227,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -32446,7 +32325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32470,7 +32349,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32531,7 +32410,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -32557,7 +32436,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD
if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -33074,9 +32953,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_UNUSED == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_UNUSED == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -33603,10 +33483,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
}
- if (IS_CV == IS_VAR && !Z_ISREF_P(retval_ptr)) {
- if (opline->extended_value == ZEND_RETURNS_FUNCTION &&
- (Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF)) {
- } else {
+ if (IS_CV == IS_VAR) {
+ if (retval_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(retval_ptr) & IS_VAR_RET_REF))) {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
ZVAL_NEW_REF(EX(return_value), retval_ptr);
@@ -34456,27 +34336,6 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_NEXT_OPCODE();
}
-static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
-
- zval *expr;
- zend_bool result;
-
- SAVE_OPLINE();
- expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
-
- if (Z_TYPE_P(expr) == IS_OBJECT) {
- result = instanceof_function(Z_OBJCE_P(expr), Z_CE_P(EX_VAR(opline->op2.var)) TSRMLS_CC);
- } else {
- result = 0;
- }
- ZVAL_BOOL(EX_VAR(opline->result.var), result);
-
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE();
-}
-
static int ZEND_FASTCALL ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -34846,7 +34705,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = opline->op2.zv;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -34869,21 +34728,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -34938,15 +34793,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -34954,9 +34813,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
} else {
zval *dim = opline->op2.zv;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CONST TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CONST TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -34967,33 +34827,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -35019,31 +34864,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -35199,7 +35030,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -35227,21 +35058,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -35293,7 +35120,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -35319,19 +35146,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -35480,9 +35303,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -35552,11 +35372,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35578,6 +35395,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35619,6 +35437,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35650,6 +35469,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -35707,7 +35527,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35731,7 +35551,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35792,7 +35612,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35818,7 +35638,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -35896,29 +35716,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = opline->op2.zv;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = opline->op2.zv;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -35932,7 +35756,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -36618,6 +36441,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_CONST == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -36664,9 +36526,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -37107,7 +36970,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -37130,21 +36993,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -37200,15 +37059,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -37216,9 +37079,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
} else {
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_TMP_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -37229,33 +37093,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -37281,30 +37131,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -37461,7 +37298,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -37489,21 +37326,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -37556,7 +37389,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -37582,19 +37415,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -37665,11 +37494,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37691,6 +37517,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37732,6 +37559,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37763,6 +37591,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -37821,7 +37650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37845,7 +37674,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37907,7 +37736,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37933,7 +37762,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -37978,29 +37807,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -38014,7 +37847,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -38605,9 +38437,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -38991,7 +38824,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -39014,21 +38847,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- if (!have_get_ptr) {
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
+
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -39084,15 +38913,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op2, free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op2, free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -39100,9 +38933,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
} else {
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_VAR TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -39113,33 +38947,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
zval_ptr_dtor_nogc(free_op2.var);
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -39165,30 +38985,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
zval_ptr_dtor_nogc(free_op2.var);
CHECK_EXCEPTION();
@@ -39345,7 +39152,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -39373,21 +39180,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -39440,7 +39243,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -39466,19 +39269,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -39628,9 +39427,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -39700,11 +39496,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39726,6 +39519,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -39767,6 +39561,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39798,6 +39593,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -39856,7 +39652,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39880,7 +39676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39942,7 +39738,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -39968,7 +39764,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -40013,29 +39809,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_free_op free_op2;
zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
zval_ptr_dtor_nogc(free_op2.var);
} else {
- zend_free_op free_op2, free_op_data1, free_op_data2;
+ zend_free_op free_op2, free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC);
- zval_ptr_dtor_nogc(free_op2.var);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC);
+ zval_ptr_dtor_nogc(free_op2.var);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -40049,7 +39849,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -40103,10 +39902,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_VAR == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!(free_op2.var != NULL)) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -40123,15 +39925,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
}
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_VAR == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -40802,6 +40603,45 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *expr;
+ zend_bool result;
+
+ SAVE_OPLINE();
+ expr = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (Z_TYPE_P(expr) == IS_OBJECT) {
+ zend_class_entry *ce;
+
+ if (IS_VAR == IS_CONST) {
+ if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
+ ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+ } else {
+ ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
+ if (UNEXPECTED(ce == NULL)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
+ }
+ } else {
+ ce = Z_CE_P(EX_VAR(opline->op2.var));
+ }
+ result = instanceof_function(Z_OBJCE_P(expr), ce TSRMLS_CC);
+ } else {
+ result = 0;
+ }
+ ZVAL_BOOL(EX_VAR(opline->result.var), result);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -40848,9 +40688,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -40959,7 +40800,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = NULL;
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -40982,21 +40823,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -41051,15 +40888,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -41067,9 +40908,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
} else {
zval *dim = NULL;
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_UNUSED TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_UNUSED TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -41080,33 +40922,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -41132,31 +40959,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -41411,9 +41224,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
}
ZVAL_COPY(EX_VAR(opline->result.var), retval);
} else {
- if (/*type == BP_VAR_W &&*/ (opline->extended_value & ZEND_FETCH_MAKE_REF)) {
- ZVAL_MAKE_REF(retval);
- }
ZVAL_INDIRECT(EX_VAR(opline->result.var), retval);
}
CHECK_EXCEPTION();
@@ -41468,11 +41278,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41494,6 +41301,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -41520,6 +41328,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -41551,29 +41360,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = NULL;
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = NULL;
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -41587,7 +41400,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -41908,9 +41720,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -42279,7 +42092,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *value;
- int have_get_ptr = 0;
+ zval *zptr;
if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
@@ -42302,21 +42115,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
} else {
/* here we are sure we are dealing with an object */
if (opline->extended_value == ZEND_ASSIGN_OBJ
- && Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
-
- have_get_ptr = 1;
- binary_op(zptr, zptr, value TSRMLS_CC);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(EX_VAR(opline->result.var), zptr);
- }
- }
- }
+ && EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
+
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ binary_op(zptr, zptr, value TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(EX_VAR(opline->result.var), zptr);
+ }
+ } else {
zval *z = NULL;
zval rv;
@@ -42371,15 +42180,19 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
- zend_free_op free_op_data2, free_op_data1;
- zval *var_ptr;
+ zend_free_op free_op_data1;
+ zval *var_ptr, rv;
zval *value, *container;
SAVE_OPLINE();
container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
- } else if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
+ }
+ if (IS_CV != IS_UNUSED) {
+ ZVAL_DEREF(container);
+ }
+ if (IS_CV == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (IS_CV == IS_VAR && !0) {
Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */
}
@@ -42387,9 +42200,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
} else {
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- zend_fetch_dimension_address_RW(EX_VAR((opline+1)->op2.var), container, dim, IS_CV TSRMLS_CC);
+ zend_fetch_dimension_address_RW(&rv, container, dim, IS_CV TSRMLS_CC);
value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ var_ptr = Z_INDIRECT(rv);
}
if (UNEXPECTED(var_ptr == NULL)) {
@@ -42400,33 +42214,18 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_dim_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_dim_exit:
-
FREE_OP(free_op_data1);
- FREE_OP_VAR_PTR(free_op_data2);
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
@@ -42452,31 +42251,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- goto assign_op_exit;
- }
-
- ZVAL_DEREF(var_ptr);
- SEPARATE_ZVAL_NOREF(var_ptr);
-
- if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_OBJECT) &&
- UNEXPECTED(Z_OBJ_HANDLER_P(var_ptr, get) && Z_OBJ_HANDLER_P(var_ptr, set))) {
- /* proxy object */
- zval rv;
- zval *objval = Z_OBJ_HANDLER_P(var_ptr, get)(var_ptr, &rv TSRMLS_CC);
- Z_ADDREF_P(objval);
- binary_op(objval, objval, value TSRMLS_CC);
- Z_OBJ_HANDLER_P(var_ptr, set)(var_ptr, objval TSRMLS_CC);
- zval_ptr_dtor(objval);
} else {
+ ZVAL_DEREF(var_ptr);
+ SEPARATE_ZVAL_NOREF(var_ptr);
+
binary_op(var_ptr, var_ptr, value TSRMLS_CC);
- }
- if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
- ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
+ ZVAL_COPY(EX_VAR(opline->result.var), var_ptr);
+ }
}
-assign_op_exit:
-
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -42632,7 +42417,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -42660,21 +42445,17 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- ZVAL_DEREF(zptr);
- SEPARATE_ZVAL_NOREF(zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- have_get_ptr = 1;
- incdec_op(zptr);
- if (RETURN_VALUE_USED(opline)) {
- ZVAL_COPY(retval, zptr);
- }
- }
- }
+ ZVAL_DEREF(zptr);
+ SEPARATE_ZVAL_NOREF(zptr);
- if (!have_get_ptr) {
+ incdec_op(zptr);
+ if (RETURN_VALUE_USED(opline)) {
+ ZVAL_COPY(retval, zptr);
+ }
+ } else {
zval rv;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
@@ -42726,7 +42507,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
zval *object;
zval *property;
zval *retval;
- int have_get_ptr = 0;
+ zval *zptr;
SAVE_OPLINE();
object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
@@ -42752,19 +42533,15 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
/* here we are sure we are dealing with an object */
- if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval *zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
- if (zptr != NULL) { /* NULL means no success in getting PTR */
- have_get_ptr = 1;
- ZVAL_DEREF(zptr);
- ZVAL_COPY(retval, zptr);
+ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
+ && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
- SEPARATE_ZVAL_NOREF(zptr);
- incdec_op(zptr);
- }
- }
+ ZVAL_DEREF(zptr);
+ ZVAL_COPY(retval, zptr);
- if (!have_get_ptr) {
+ SEPARATE_ZVAL_NOREF(zptr);
+ incdec_op(zptr);
+ } else {
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
zval rv;
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
@@ -42834,11 +42611,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (EXPECTED(opline->extended_value == 0)) {
- zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- } else {
- zend_fetch_dimension_address_W_ref(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
- }
+ ZVAL_DEREF(container);
+ zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42860,6 +42634,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -42901,6 +42676,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -42932,6 +42708,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
+ ZVAL_DEREF(container);
zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
@@ -42989,7 +42766,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, (opline->extended_value & ZEND_FETCH_MAKE_REF) != 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43013,7 +42790,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43074,7 +42851,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43100,7 +42877,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
- zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC);
+ zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
@@ -43145,29 +42922,33 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) {
- object_ptr = Z_REFVAL_P(object_ptr);
- }
- if (Z_TYPE_P(object_ptr) == IS_OBJECT) {
+ ZVAL_DEREF(object_ptr);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
} else {
- zend_free_op free_op_data1, free_op_data2;
+ zend_free_op free_op_data1;
+ zval rv;
zval *value;
zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval *variable_ptr;
- variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC);
+ if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) &&
+ EXPECTED(Z_STRLEN_P(object_ptr) != 0)) {
+ zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
- if (UNEXPECTED(variable_ptr != NULL)) {
- zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC);
FREE_OP(free_op_data1);
} else {
- variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
+ zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV TSRMLS_CC);
+
+ value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT);
+ variable_ptr = Z_INDIRECT(rv);
if (UNEXPECTED(variable_ptr == &EG(error_zval))) {
FREE_OP(free_op_data1);
if (RETURN_VALUE_USED(opline)) {
@@ -43181,7 +42962,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (RETURN_VALUE_USED(opline)) {
ZVAL_COPY(EX_VAR(opline->result.var), value);
}
- FREE_OP_VAR_PTR(free_op_data2);
}
}
}
@@ -43234,10 +43014,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
- opline->extended_value == ZEND_RETURNS_FUNCTION &&
- !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF) &&
- !Z_ISREF_P(value_ptr)) {
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
if (!0) {
PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */
}
@@ -43254,15 +43037,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
}
variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
+ }
if (IS_CV == IS_VAR &&
UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT) &&
UNEXPECTED(!Z_ISREF_P(variable_ptr))) {
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) ||
- (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) {
- zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
- }
if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) ||
(IS_CV == IS_VAR && UNEXPECTED(value_ptr == &EG(error_zval)))) {
variable_ptr = &EG(uninitialized_zval);
@@ -43829,9 +43611,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
/* If a function call result is yielded and the function did
* not return by reference we throw a notice. */
- if (IS_CV == IS_VAR && !Z_ISREF_P(value_ptr)
- && !(opline->extended_value == ZEND_RETURNS_FUNCTION
- && (Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF))) {
+ if (IS_CV == IS_VAR &&
+ (value_ptr == &EG(uninitialized_zval) ||
+ (opline->extended_value == ZEND_RETURNS_FUNCTION &&
+ !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
} else {
ZVAL_MAKE_REF(value_ptr);
@@ -45643,31 +45426,31 @@ void zend_init_opcodes_handlers(void)
ZEND_SEND_REF_SPEC_CV_HANDLER,
ZEND_SEND_REF_SPEC_CV_HANDLER,
ZEND_SEND_REF_SPEC_CV_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
- ZEND_NEW_SPEC_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NEW_SPEC_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NEW_SPEC_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
@@ -47398,26 +47181,26 @@ void zend_init_opcodes_handlers(void)
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_TMP_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
- ZEND_INSTANCEOF_SPEC_VAR_HANDLER,
+ ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
+ ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER,
ZEND_NULL_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
- ZEND_INSTANCEOF_SPEC_CV_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,
ZEND_DECLARE_CLASS_SPEC_HANDLER,