mirror of
https://github.com/php/php-src.git
synced 2026-03-31 20:53:00 +02:00
Merge branch 'PHP-8.0'
* PHP-8.0: Provide unused retvals to observers
This commit is contained in:
@@ -4239,9 +4239,11 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER))
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
ZEND_OBSERVER_USE_RETVAL;
|
||||
|
||||
retval_ptr = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
return_value = EX(return_value);
|
||||
ZEND_OBSERVER_SET_RETVAL();
|
||||
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -4305,6 +4307,7 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER))
|
||||
}
|
||||
ZEND_OBSERVER_SAVE_OPLINE();
|
||||
ZEND_OBSERVER_FCALL_END(execute_data, return_value);
|
||||
ZEND_OBSERVER_FREE_RETVAL();
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
|
||||
@@ -4312,9 +4315,13 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
ZEND_OBSERVER_USE_RETVAL;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
return_value = EX(return_value);
|
||||
ZEND_OBSERVER_SET_RETVAL();
|
||||
do {
|
||||
if ((OP1_TYPE & (IS_CONST|IS_TMP_VAR)) ||
|
||||
(OP1_TYPE == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
|
||||
@@ -4322,15 +4329,15 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
|
||||
retval_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
if (!EX(return_value)) {
|
||||
if (!return_value) {
|
||||
FREE_OP1();
|
||||
} else {
|
||||
if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
|
||||
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
|
||||
ZVAL_COPY_VALUE(return_value, retval_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
Z_TRY_ADDREF_P(retval_ptr);
|
||||
}
|
||||
@@ -4344,8 +4351,8 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
|
||||
ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
|
||||
if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
if (EX(return_value)) {
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
if (return_value) {
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
} else {
|
||||
FREE_OP1_VAR_PTR();
|
||||
}
|
||||
@@ -4353,19 +4360,20 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
|
||||
}
|
||||
}
|
||||
|
||||
if (EX(return_value)) {
|
||||
if (return_value) {
|
||||
if (Z_ISREF_P(retval_ptr)) {
|
||||
Z_ADDREF_P(retval_ptr);
|
||||
} else {
|
||||
ZVAL_MAKE_REF_EX(retval_ptr, 2);
|
||||
}
|
||||
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
|
||||
ZVAL_REF(return_value, Z_REF_P(retval_ptr));
|
||||
}
|
||||
|
||||
FREE_OP1_VAR_PTR();
|
||||
} while (0);
|
||||
|
||||
ZEND_OBSERVER_FCALL_END(execute_data, EX(return_value));
|
||||
ZEND_OBSERVER_FCALL_END(execute_data, return_value);
|
||||
ZEND_OBSERVER_FREE_RETVAL();
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||
}
|
||||
|
||||
@@ -7710,7 +7718,7 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca
|
||||
|
||||
/* Uncaught exception */
|
||||
if (zend_observer_fcall_op_array_extension != -1) {
|
||||
zend_observer_fcall_end(execute_data, EX(return_value));
|
||||
zend_observer_fcall_end(execute_data, NULL);
|
||||
}
|
||||
cleanup_live_vars(execute_data, op_num, 0);
|
||||
if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
|
||||
|
||||
@@ -2905,7 +2905,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
|
||||
|
||||
/* Uncaught exception */
|
||||
if (zend_observer_fcall_op_array_extension != -1) {
|
||||
zend_observer_fcall_end(execute_data, EX(return_value));
|
||||
zend_observer_fcall_end(execute_data, NULL);
|
||||
}
|
||||
cleanup_live_vars(execute_data, op_num, 0);
|
||||
if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) {
|
||||
@@ -4021,6 +4021,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_
|
||||
|
||||
retval_ptr = RT_CONSTANT(opline, opline->op1);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -4084,6 +4085,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -4092,9 +4094,11 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_OBSER
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
zval observer_retval;
|
||||
|
||||
retval_ptr = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R);
|
||||
return_value = EX(return_value);
|
||||
if (!return_value) { return_value = &observer_retval; };
|
||||
if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -4158,6 +4162,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_OBSER
|
||||
}
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_end(execute_data, return_value);
|
||||
if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); };
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -4165,9 +4170,12 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
return_value = EX(return_value);
|
||||
|
||||
do {
|
||||
if ((IS_CONST & (IS_CONST|IS_TMP_VAR)) ||
|
||||
(IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
|
||||
@@ -4175,15 +4183,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
|
||||
retval_ptr = RT_CONSTANT(opline, opline->op1);
|
||||
if (!EX(return_value)) {
|
||||
if (!return_value) {
|
||||
|
||||
} else {
|
||||
if (IS_CONST == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
|
||||
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
|
||||
ZVAL_COPY_VALUE(return_value, retval_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
if (IS_CONST == IS_CONST) {
|
||||
Z_TRY_ADDREF_P(retval_ptr);
|
||||
}
|
||||
@@ -4197,8 +4205,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
|
||||
if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
if (EX(return_value)) {
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
if (return_value) {
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
} else {
|
||||
|
||||
}
|
||||
@@ -4206,17 +4214,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
}
|
||||
}
|
||||
|
||||
if (EX(return_value)) {
|
||||
if (return_value) {
|
||||
if (Z_ISREF_P(retval_ptr)) {
|
||||
Z_ADDREF_P(retval_ptr);
|
||||
} else {
|
||||
ZVAL_MAKE_REF_EX(retval_ptr, 2);
|
||||
}
|
||||
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
|
||||
ZVAL_REF(return_value, Z_REF_P(retval_ptr));
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -4224,9 +4233,13 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
zval observer_retval;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
return_value = EX(return_value);
|
||||
if (!return_value) { return_value = &observer_retval; };
|
||||
do {
|
||||
if ((opline->op1_type & (IS_CONST|IS_TMP_VAR)) ||
|
||||
(opline->op1_type == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
|
||||
@@ -4234,15 +4247,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
|
||||
retval_ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R);
|
||||
if (!EX(return_value)) {
|
||||
if (!return_value) {
|
||||
FREE_OP(opline->op1_type, opline->op1.var);
|
||||
} else {
|
||||
if (opline->op1_type == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
|
||||
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
|
||||
ZVAL_COPY_VALUE(return_value, retval_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
Z_TRY_ADDREF_P(retval_ptr);
|
||||
}
|
||||
@@ -4256,8 +4269,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
|
||||
if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
if (EX(return_value)) {
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
if (return_value) {
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
} else {
|
||||
if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));};
|
||||
}
|
||||
@@ -4265,19 +4278,20 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPE
|
||||
}
|
||||
}
|
||||
|
||||
if (EX(return_value)) {
|
||||
if (return_value) {
|
||||
if (Z_ISREF_P(retval_ptr)) {
|
||||
Z_ADDREF_P(retval_ptr);
|
||||
} else {
|
||||
ZVAL_MAKE_REF_EX(retval_ptr, 2);
|
||||
}
|
||||
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
|
||||
ZVAL_REF(return_value, Z_REF_P(retval_ptr));
|
||||
}
|
||||
|
||||
if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));};
|
||||
} while (0);
|
||||
|
||||
zend_observer_fcall_end(execute_data, EX(return_value));
|
||||
zend_observer_fcall_end(execute_data, return_value);
|
||||
if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); };
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -18528,6 +18542,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA
|
||||
|
||||
retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -18591,6 +18606,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -18598,9 +18614,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
return_value = EX(return_value);
|
||||
|
||||
do {
|
||||
if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) ||
|
||||
(IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
|
||||
@@ -18608,15 +18627,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
|
||||
retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
|
||||
if (!EX(return_value)) {
|
||||
if (!return_value) {
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
|
||||
} else {
|
||||
if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
|
||||
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
|
||||
ZVAL_COPY_VALUE(return_value, retval_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
if (IS_TMP_VAR == IS_CONST) {
|
||||
Z_TRY_ADDREF_P(retval_ptr);
|
||||
}
|
||||
@@ -18630,8 +18649,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
|
||||
ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
|
||||
if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
if (EX(return_value)) {
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
if (return_value) {
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
} else {
|
||||
|
||||
}
|
||||
@@ -18639,17 +18658,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
|
||||
}
|
||||
}
|
||||
|
||||
if (EX(return_value)) {
|
||||
if (return_value) {
|
||||
if (Z_ISREF_P(retval_ptr)) {
|
||||
Z_ADDREF_P(retval_ptr);
|
||||
} else {
|
||||
ZVAL_MAKE_REF_EX(retval_ptr, 2);
|
||||
}
|
||||
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
|
||||
ZVAL_REF(return_value, Z_REF_P(retval_ptr));
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -21094,6 +21114,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA
|
||||
|
||||
retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -21157,6 +21178,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -21164,9 +21186,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
return_value = EX(return_value);
|
||||
|
||||
do {
|
||||
if ((IS_VAR & (IS_CONST|IS_TMP_VAR)) ||
|
||||
(IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
|
||||
@@ -21174,15 +21199,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
|
||||
retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
|
||||
if (!EX(return_value)) {
|
||||
if (!return_value) {
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
|
||||
} else {
|
||||
if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
|
||||
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
|
||||
ZVAL_COPY_VALUE(return_value, retval_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
if (IS_VAR == IS_CONST) {
|
||||
Z_TRY_ADDREF_P(retval_ptr);
|
||||
}
|
||||
@@ -21196,8 +21221,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
|
||||
ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
|
||||
if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
if (EX(return_value)) {
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
if (return_value) {
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
} else {
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
|
||||
}
|
||||
@@ -21205,18 +21230,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
|
||||
}
|
||||
}
|
||||
|
||||
if (EX(return_value)) {
|
||||
if (return_value) {
|
||||
if (Z_ISREF_P(retval_ptr)) {
|
||||
Z_ADDREF_P(retval_ptr);
|
||||
} else {
|
||||
ZVAL_MAKE_REF_EX(retval_ptr, 2);
|
||||
}
|
||||
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
|
||||
ZVAL_REF(return_value, Z_REF_P(retval_ptr));
|
||||
}
|
||||
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
|
||||
} while (0);
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -37626,6 +37652,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN
|
||||
|
||||
retval_ptr = EX_VAR(opline->op1.var);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -37689,6 +37716,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN
|
||||
}
|
||||
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -37696,9 +37724,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
|
||||
SAVE_OPLINE();
|
||||
|
||||
return_value = EX(return_value);
|
||||
|
||||
do {
|
||||
if ((IS_CV & (IS_CONST|IS_TMP_VAR)) ||
|
||||
(IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) {
|
||||
@@ -37706,15 +37737,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
|
||||
retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
|
||||
if (!EX(return_value)) {
|
||||
if (!return_value) {
|
||||
|
||||
} else {
|
||||
if (IS_CV == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) {
|
||||
ZVAL_COPY_VALUE(EX(return_value), retval_ptr);
|
||||
ZVAL_COPY_VALUE(return_value, retval_ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
if (IS_CV == IS_CONST) {
|
||||
Z_TRY_ADDREF_P(retval_ptr);
|
||||
}
|
||||
@@ -37728,8 +37759,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
|
||||
ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval));
|
||||
if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) {
|
||||
zend_error(E_NOTICE, "Only variable references should be returned by reference");
|
||||
if (EX(return_value)) {
|
||||
ZVAL_NEW_REF(EX(return_value), retval_ptr);
|
||||
if (return_value) {
|
||||
ZVAL_NEW_REF(return_value, retval_ptr);
|
||||
} else {
|
||||
|
||||
}
|
||||
@@ -37737,17 +37768,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
|
||||
}
|
||||
}
|
||||
|
||||
if (EX(return_value)) {
|
||||
if (return_value) {
|
||||
if (Z_ISREF_P(retval_ptr)) {
|
||||
Z_ADDREF_P(retval_ptr);
|
||||
} else {
|
||||
ZVAL_MAKE_REF_EX(retval_ptr, 2);
|
||||
}
|
||||
ZVAL_REF(EX(return_value), Z_REF_P(retval_ptr));
|
||||
ZVAL_REF(return_value, Z_REF_P(retval_ptr));
|
||||
}
|
||||
|
||||
} while (0);
|
||||
|
||||
|
||||
ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));
|
||||
}
|
||||
|
||||
@@ -54693,6 +54725,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
|
||||
retval_ptr = RT_CONSTANT(opline, opline->op1);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -54756,6 +54789,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@@ -54765,9 +54799,11 @@ zend_leave_helper_SPEC_LABEL:
|
||||
USE_OPLINE
|
||||
zval *retval_ptr;
|
||||
zval *return_value;
|
||||
zval observer_retval;
|
||||
|
||||
retval_ptr = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R);
|
||||
return_value = EX(return_value);
|
||||
if (!return_value) { return_value = &observer_retval; };
|
||||
if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -54831,6 +54867,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
SAVE_OPLINE();
|
||||
zend_observer_fcall_end(execute_data, return_value);
|
||||
if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); };
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@@ -56303,6 +56340,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
|
||||
retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -56366,6 +56404,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@@ -56602,6 +56641,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
|
||||
retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -56665,6 +56705,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
@@ -57717,6 +57758,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
|
||||
retval_ptr = EX_VAR(opline->op1.var);
|
||||
return_value = EX(return_value);
|
||||
|
||||
if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) {
|
||||
SAVE_OPLINE();
|
||||
retval_ptr = ZVAL_UNDEFINED_OP1();
|
||||
@@ -57780,6 +57822,7 @@ zend_leave_helper_SPEC_LABEL:
|
||||
}
|
||||
|
||||
|
||||
|
||||
goto zend_leave_helper_SPEC_LABEL;
|
||||
}
|
||||
|
||||
|
||||
@@ -794,6 +794,9 @@ function gen_code($f, $spec, $kind, $code, $op1, $op2, $name, $extra_spec=null)
|
||||
($extra_spec['ISSET'] == 0 ? "\\0" : "opline->extended_value")
|
||||
: "\\0",
|
||||
"/ZEND_OBSERVER_ENABLED/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "1" : "0",
|
||||
"/ZEND_OBSERVER_USE_RETVAL/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "zval observer_retval" : "",
|
||||
"/ZEND_OBSERVER_SET_RETVAL\(\)/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "if (!return_value) { return_value = &observer_retval; }" : "",
|
||||
"/ZEND_OBSERVER_FREE_RETVAL\(\)/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }" : "",
|
||||
"/ZEND_OBSERVER_SAVE_OPLINE\(\)/" => isset($extra_spec['OBSERVER']) && $extra_spec['OBSERVER'] == 1 ? "SAVE_OPLINE()" : "",
|
||||
"/ZEND_OBSERVER_FCALL_BEGIN\(\s*(.*)\s*\)/" => isset($extra_spec['OBSERVER']) ?
|
||||
($extra_spec['OBSERVER'] == 0 ? "" : "zend_observer_fcall_begin(\\1)")
|
||||
|
||||
@@ -480,7 +480,14 @@ static void get_retval_info(zval *retval, smart_str *buf)
|
||||
if (retval == NULL) {
|
||||
smart_str_appendl(buf, "NULL", 4);
|
||||
} else if (ZT_G(observer_show_return_value)) {
|
||||
php_var_export_ex(retval, 2 * ZT_G(observer_nesting_depth) + 3, buf);
|
||||
if (Z_TYPE_P(retval) == IS_OBJECT) {
|
||||
smart_str_appendl(buf, "object(", 7);
|
||||
smart_str_append(buf, Z_OBJCE_P(retval)->name);
|
||||
smart_str_appendl(buf, ")#", 2);
|
||||
smart_str_append_long(buf, Z_OBJ_HANDLE_P(retval));
|
||||
} else {
|
||||
php_var_export_ex(retval, 2 * ZT_G(observer_nesting_depth) + 3, buf);
|
||||
}
|
||||
} else if (ZT_G(observer_show_return_type)) {
|
||||
smart_str_appends(buf, zend_zval_type_name(retval));
|
||||
}
|
||||
|
||||
29
ext/zend_test/tests/observer_retval_01.phpt
Normal file
29
ext/zend_test/tests/observer_retval_01.phpt
Normal file
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
Observer: Retvals are observable that are: IS_CONST
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
return 'I should be observable'; // IS_CONST
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
32
ext/zend_test/tests/observer_retval_02.phpt
Normal file
32
ext/zend_test/tests/observer_retval_02.phpt
Normal file
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
Observer: Unused retvals from generators are still observable
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
yield 'I should be observable';
|
||||
yield 'Me too!';
|
||||
}
|
||||
|
||||
$gen = foo();
|
||||
$gen->current();
|
||||
$gen->next();
|
||||
$gen->current();
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
</foo:'Me too!'>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
32
ext/zend_test/tests/observer_retval_03.phpt
Normal file
32
ext/zend_test/tests/observer_retval_03.phpt
Normal file
@@ -0,0 +1,32 @@
|
||||
--TEST--
|
||||
Observer: Retvals are observable that are: refcounted, IS_CV
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
class MyRetval {}
|
||||
|
||||
function foo() {
|
||||
$retval = new MyRetval(); // Refcounted
|
||||
return $retval; // IS_CV
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
</foo:object(MyRetval)#%d>
|
||||
<foo>
|
||||
</foo:object(MyRetval)#%d>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
52
ext/zend_test/tests/observer_retval_04.phpt
Normal file
52
ext/zend_test/tests/observer_retval_04.phpt
Normal file
@@ -0,0 +1,52 @@
|
||||
--TEST--
|
||||
Observer: Retvals are observable that are: refcounted, IS_VAR
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
class MyRetval {}
|
||||
|
||||
function getObj() {
|
||||
return new MyRetval(); // Refcounted
|
||||
}
|
||||
|
||||
function foo() {
|
||||
return getObj(); // IS_VAR
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
function bar($what) {
|
||||
return 'This gets ' . $what . ' in the return handler when unused'; // Refcounted + IS_VAR
|
||||
}
|
||||
|
||||
$res = bar('freed'); // Retval used
|
||||
bar('freed'); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init getObj() -->
|
||||
<getObj>
|
||||
</getObj:object(MyRetval)#%d>
|
||||
</foo:object(MyRetval)#%d>
|
||||
<foo>
|
||||
<getObj>
|
||||
</getObj:object(MyRetval)#%d>
|
||||
</foo:object(MyRetval)#%d>
|
||||
<!-- init bar() -->
|
||||
<bar>
|
||||
</bar:'This gets freed in the return handler when unused'>
|
||||
<bar>
|
||||
</bar:'This gets freed in the return handler when unused'>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
33
ext/zend_test/tests/observer_retval_05.phpt
Normal file
33
ext/zend_test/tests/observer_retval_05.phpt
Normal file
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Observer: Retvals are observable that are: IS_CV, IS_UNDEF
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
return $i_do_not_exist; // IS_CV && IS_UNDEF
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
|
||||
Warning: Undefined variable $i_do_not_exist in %s on line %d
|
||||
</foo:NULL>
|
||||
<foo>
|
||||
|
||||
Warning: Undefined variable $i_do_not_exist in %s on line %d
|
||||
</foo:NULL>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
30
ext/zend_test/tests/observer_retval_06.phpt
Normal file
30
ext/zend_test/tests/observer_retval_06.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Observer: Retvals are observable that are: IS_CV
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function foo() {
|
||||
$retval = 'I should be observable';
|
||||
return $retval; // IS_CV
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
39
ext/zend_test/tests/observer_retval_07.phpt
Normal file
39
ext/zend_test/tests/observer_retval_07.phpt
Normal file
@@ -0,0 +1,39 @@
|
||||
--TEST--
|
||||
Observer: Retvals are observable that are: IS_REFERENCE, IS_VAR
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function &getMessage() {
|
||||
$retval = 'I should be observable';
|
||||
return $retval;
|
||||
}
|
||||
|
||||
function foo() {
|
||||
return getMessage(); // IS_REFERENCE + IS_VAR
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_%d.php' -->
|
||||
<file '%s/observer_retval_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init getMessage() -->
|
||||
<getMessage>
|
||||
</getMessage:'I should be observable'>
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
<getMessage>
|
||||
</getMessage:'I should be observable'>
|
||||
</foo:'I should be observable'>
|
||||
Done
|
||||
</file '%s/observer_retval_%d.php'>
|
||||
30
ext/zend_test/tests/observer_retval_by_ref_01.phpt
Normal file
30
ext/zend_test/tests/observer_retval_by_ref_01.phpt
Normal file
@@ -0,0 +1,30 @@
|
||||
--TEST--
|
||||
Observer: Retvals by reference are observable that are: IS_CV
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function &foo() {
|
||||
$retval = 'I should be observable';
|
||||
return $retval; // IS_CV
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_by_ref_%d.php' -->
|
||||
<file '%s/observer_retval_by_ref_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
</foo:'I should be observable'>
|
||||
Done
|
||||
</file '%s/observer_retval_by_ref_%d.php'>
|
||||
34
ext/zend_test/tests/observer_retval_by_ref_02.phpt
Normal file
34
ext/zend_test/tests/observer_retval_by_ref_02.phpt
Normal file
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
Observer: Retvals by reference are observable that are: IS_TMP_VAR
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function &foo() {
|
||||
$retval = 'I should be ';
|
||||
return $retval . 'observable'; // IS_TMP_VAR
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_by_ref_%d.php' -->
|
||||
<file '%s/observer_retval_by_ref_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
|
||||
Notice: Only variable references should be returned by reference in %s on line %d
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
|
||||
Notice: Only variable references should be returned by reference in %s on line %d
|
||||
</foo:'I should be observable'>
|
||||
Done
|
||||
</file '%s/observer_retval_by_ref_%d.php'>
|
||||
42
ext/zend_test/tests/observer_retval_by_ref_03.phpt
Normal file
42
ext/zend_test/tests/observer_retval_by_ref_03.phpt
Normal file
@@ -0,0 +1,42 @@
|
||||
--TEST--
|
||||
Observer: Retvals by reference are observable that are: IS_VAR, ZEND_RETURNS_FUNCTION
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
function getMessage() {
|
||||
return 'I should be observable';
|
||||
}
|
||||
|
||||
function &foo() {
|
||||
return getMessage(); // IS_VAR + ZEND_RETURNS_FUNCTION
|
||||
}
|
||||
|
||||
$res = foo(); // Retval used
|
||||
foo(); // Retval unused
|
||||
|
||||
echo 'Done' . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_retval_by_ref_%d.php' -->
|
||||
<file '%s/observer_retval_by_ref_%d.php'>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<!-- init getMessage() -->
|
||||
<getMessage>
|
||||
</getMessage:'I should be observable'>
|
||||
|
||||
Notice: Only variable references should be returned by reference in %s on line %d
|
||||
</foo:'I should be observable'>
|
||||
<foo>
|
||||
<getMessage>
|
||||
</getMessage:'I should be observable'>
|
||||
|
||||
Notice: Only variable references should be returned by reference in %s on line %d
|
||||
</foo:'I should be observable'>
|
||||
Done
|
||||
</file '%s/observer_retval_by_ref_%d.php'>
|
||||
44
ext/zend_test/tests/observer_shutdown_01.phpt
Normal file
44
ext/zend_test/tests/observer_shutdown_01.phpt
Normal file
@@ -0,0 +1,44 @@
|
||||
--TEST--
|
||||
Observer: Function calls from a shutdown handler are observable
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
register_shutdown_function(function () {
|
||||
echo 'Shutdown: ' . foo() . PHP_EOL;
|
||||
});
|
||||
|
||||
function bar() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
function foo() {
|
||||
bar();
|
||||
return bar();
|
||||
}
|
||||
|
||||
echo 'Done: ' . bar() . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_shutdown_%d.php' -->
|
||||
<file '%s/observer_shutdown_%d.php'>
|
||||
<!-- init bar() -->
|
||||
<bar>
|
||||
</bar:42>
|
||||
Done: 42
|
||||
</file '%s/observer_shutdown_%d.php'>
|
||||
<!-- init {closure}() -->
|
||||
<{closure}>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<bar>
|
||||
</bar:42>
|
||||
<bar>
|
||||
</bar:42>
|
||||
</foo:42>
|
||||
Shutdown: 42
|
||||
</{closure}:NULL>
|
||||
50
ext/zend_test/tests/observer_shutdown_02.phpt
Normal file
50
ext/zend_test/tests/observer_shutdown_02.phpt
Normal file
@@ -0,0 +1,50 @@
|
||||
--TEST--
|
||||
Observer: Function calls from a __destruct during shutdown are observable
|
||||
--SKIPIF--
|
||||
<?php if (!extension_loaded('zend-test')) die('skip: zend-test extension required'); ?>
|
||||
--INI--
|
||||
zend_test.observer.enabled=1
|
||||
zend_test.observer.observe_all=1
|
||||
zend_test.observer.show_return_value=1
|
||||
--FILE--
|
||||
<?php
|
||||
class MyClass
|
||||
{
|
||||
public function __destruct()
|
||||
{
|
||||
echo 'Shutdown: ' . foo() . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
function bar() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
function foo() {
|
||||
bar();
|
||||
return bar();
|
||||
}
|
||||
|
||||
$mc = new MyClass();
|
||||
|
||||
echo 'Done: ' . bar() . PHP_EOL;
|
||||
?>
|
||||
--EXPECTF--
|
||||
<!-- init '%s/observer_shutdown_%d.php' -->
|
||||
<file '%s/observer_shutdown_%d.php'>
|
||||
<!-- init bar() -->
|
||||
<bar>
|
||||
</bar:42>
|
||||
Done: 42
|
||||
</file '%s/observer_shutdown_%d.php'>
|
||||
<!-- init MyClass::__destruct() -->
|
||||
<MyClass::__destruct>
|
||||
<!-- init foo() -->
|
||||
<foo>
|
||||
<bar>
|
||||
</bar:42>
|
||||
<bar>
|
||||
</bar:42>
|
||||
</foo:42>
|
||||
Shutdown: 42
|
||||
</MyClass::__destruct:NULL>
|
||||
Reference in New Issue
Block a user