Browse Source

Cheaper reference construction

pull/2988/merge
Dmitry Stogov 8 years ago
parent
commit
efcbea4345
  1. 18
      Zend/zend_inheritance.c
  2. 11
      Zend/zend_types.h
  3. 64
      Zend/zend_vm_def.h
  4. 425
      Zend/zend_vm_execute.h
  5. 102
      ext/standard/array.c

18
Zend/zend_inheritance.c

@ -896,18 +896,24 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
do {
dst--;
src--;
ZVAL_MAKE_REF(src);
ZVAL_COPY_VALUE(dst, src);
Z_ADDREF_P(dst);
if (Z_ISREF_P(src)) {
Z_ADDREF_P(src);
} else {
ZVAL_MAKE_REF_EX(src, 2);
}
ZVAL_REF(dst, Z_REF_P(src));
} while (dst != end);
} else if (ce->type == ZEND_USER_CLASS) {
src = parent_ce->default_static_members_table + parent_ce->default_static_members_count;
do {
dst--;
src--;
ZVAL_MAKE_REF(src);
ZVAL_COPY_VALUE(dst, src);
Z_ADDREF_P(dst);
if (Z_ISREF_P(src)) {
Z_ADDREF_P(src);
} else {
ZVAL_MAKE_REF_EX(src, 2);
}
ZVAL_REF(dst, Z_REF_P(src));
if (Z_TYPE_P(Z_REFVAL_P(dst)) == IS_CONSTANT_AST) {
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
}

11
Zend/zend_types.h

@ -808,6 +808,17 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
Z_TYPE_INFO_P(z) = IS_REFERENCE_EX; \
} while (0)
#define ZVAL_MAKE_REF_EX(z, refcount) do { \
zval *_z = (z); \
zend_reference *_ref = \
(zend_reference *) emalloc(sizeof(zend_reference)); \
GC_SET_REFCOUNT(_ref, (refcount)); \
GC_TYPE_INFO(_ref) = IS_REFERENCE; \
ZVAL_COPY_VALUE(&_ref->val, _z); \
Z_REF_P(_z) = _ref; \
Z_TYPE_INFO_P(_z) = IS_REFERENCE_EX; \
} while (0)
#define ZVAL_NEW_PERSISTENT_REF(z, r) do { \
zend_reference *_ref = \
(zend_reference *) malloc(sizeof(zend_reference)); \

64
Zend/zend_vm_def.h

@ -3914,8 +3914,11 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC)
}
if (EX(return_value)) {
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
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));
}
@ -4305,12 +4308,10 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, NUM)
if (Z_ISREF_P(varptr)) {
Z_ADDREF_P(varptr);
ZVAL_COPY_VALUE(arg, varptr);
} else {
ZVAL_NEW_REF(arg, varptr);
Z_ADDREF_P(arg);
ZVAL_REF(varptr, Z_REF_P(arg));
ZVAL_MAKE_REF_EX(varptr, 2);
}
ZVAL_REF(arg, Z_REF_P(varptr));
FREE_OP1_VAR_PTR();
ZEND_VM_NEXT_OPCODE();
@ -4411,8 +4412,11 @@ ZEND_VM_C_LABEL(send_again):
top = ZEND_CALL_ARG(EX(call), arg_num);
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
if (Z_REFCOUNT_P(args) == 1) {
ZVAL_MAKE_REF(arg);
Z_ADDREF_P(arg);
if (Z_ISREF_P(arg)) {
Z_ADDREF_P(arg);
} else {
ZVAL_MAKE_REF_EX(arg, 2);
}
ZVAL_REF(top, Z_REF_P(arg));
} else {
ZVAL_DUP(top, arg);
@ -5116,8 +5120,11 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSE
if ((OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
FREE_OP1_VAR_PTR();
} else {
expr_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
@ -7266,10 +7273,15 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
FREE_OP1_VAR_PTR();
}
@ -7568,12 +7580,8 @@ ZEND_VM_C_LABEL(check_indirect):
}
if (UNEXPECTED(!Z_ISREF_P(value))) {
ref = (zend_reference*)emalloc(sizeof(zend_reference));
GC_SET_REFCOUNT(ref, 2);
GC_TYPE_INFO(ref) = IS_REFERENCE;
ZVAL_COPY_VALUE(&ref->val, value);
Z_REF_P(value) = ref;
Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
ZVAL_MAKE_REF_EX(value, 2);
ref = Z_REF_P(value);
} else {
ref = Z_REF_P(value);
GC_ADDREF(ref);
@ -7912,8 +7920,11 @@ ZEND_VM_HANDLER(182, ZEND_BIND_LEXICAL, TMP, CV, REF)
if (opline->extended_value) {
/* By-ref binding */
var = GET_OP2_ZVAL_PTR(BP_VAR_W);
ZVAL_MAKE_REF(var);
Z_ADDREF_P(var);
if (Z_ISREF_P(var)) {
Z_ADDREF_P(var);
} else {
ZVAL_MAKE_REF_EX(var, 2);
}
} else {
var = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if (UNEXPECTED(Z_ISUNDEF_P(var))) {
@ -8034,15 +8045,20 @@ ZEND_VM_HANDLER(51, ZEND_MAKE_REF, VAR|CV, UNUSED)
ZVAL_NULL(Z_REFVAL_P(op1));
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
} else {
ZVAL_MAKE_REF(op1);
ZVAL_COPY(EX_VAR(opline->result.var), op1);
if (Z_ISREF_P(op1)) {
Z_ADDREF_P(op1);
} else {
ZVAL_MAKE_REF_EX(op1, 2);
}
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) {
op1 = Z_INDIRECT_P(op1);
if (EXPECTED(!Z_ISREF_P(op1))) {
ZVAL_MAKE_REF(op1);
ZVAL_MAKE_REF_EX(op1, 2);
} else {
GC_ADDREF(Z_REF_P(op1));
}
GC_ADDREF(Z_REF_P(op1));
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
} else {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1);

425
Zend/zend_vm_execute.h

@ -1235,8 +1235,11 @@ send_again:
top = ZEND_CALL_ARG(EX(call), arg_num);
if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
if (Z_REFCOUNT_P(args) == 1) {
ZVAL_MAKE_REF(arg);
Z_ADDREF_P(arg);
if (Z_ISREF_P(arg)) {
Z_ADDREF_P(arg);
} else {
ZVAL_MAKE_REF_EX(arg, 2);
}
ZVAL_REF(top, Z_REF_P(arg));
} else {
ZVAL_DUP(top, arg);
@ -3012,8 +3015,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDL
}
if (EX(return_value)) {
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
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));
}
@ -5830,8 +5836,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = RT_CONSTANT(opline, opline->op1);
@ -6339,10 +6348,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -8014,8 +8028,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_T
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = RT_CONSTANT(opline, opline->op1);
@ -8391,10 +8408,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(Z
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -8743,10 +8765,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(Z
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -9300,8 +9327,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_U
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = RT_CONSTANT(opline, opline->op1);
@ -9700,10 +9730,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLE
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -11240,8 +11275,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_C
if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = RT_CONSTANT(opline, opline->op1);
@ -11568,10 +11606,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZE
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -18625,8 +18668,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER
}
if (EX(return_value)) {
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
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));
}
@ -19601,8 +19647,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CON
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -19753,10 +19802,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(Z
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -20030,8 +20084,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -20218,10 +20275,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEN
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -20354,10 +20416,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEN
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -20527,8 +20594,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNU
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -20679,10 +20749,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -21012,8 +21087,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_
if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = NULL;
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -21164,10 +21242,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -21261,8 +21344,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDL
if (opline->extended_value) {
/* By-ref binding */
var = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC);
ZVAL_MAKE_REF(var);
Z_ADDREF_P(var);
if (Z_ISREF_P(var)) {
Z_ADDREF_P(var);
} else {
ZVAL_MAKE_REF_EX(var, 2);
}
} else {
var = _get_zval_ptr_cv_undef(opline->op2.var EXECUTE_DATA_CC);
if (UNEXPECTED(Z_ISUNDEF_P(var))) {
@ -21613,8 +21699,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER
}
if (EX(return_value)) {
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
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));
}
@ -21865,12 +21954,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND
if (Z_ISREF_P(varptr)) {
Z_ADDREF_P(varptr);
ZVAL_COPY_VALUE(arg, varptr);
} else {
ZVAL_NEW_REF(arg, varptr);
Z_ADDREF_P(arg);
ZVAL_REF(varptr, Z_REF_P(arg));
ZVAL_MAKE_REF_EX(varptr, 2);
}
ZVAL_REF(arg, Z_REF_P(varptr));
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
ZEND_VM_NEXT_OPCODE();
@ -25137,8 +25224,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CON
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -25416,10 +25506,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(Z
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
@ -27436,8 +27531,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -27809,10 +27907,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEN
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
@ -28096,10 +28199,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEN
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
@ -28994,8 +29102,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNU
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -29161,10 +29272,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
@ -29260,15 +29376,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDL
ZVAL_NULL(Z_REFVAL_P(op1));
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
} else {
ZVAL_MAKE_REF(op1);
ZVAL_COPY(EX_VAR(opline->result.var), op1);
if (Z_ISREF_P(op1)) {
Z_ADDREF_P(op1);
} else {
ZVAL_MAKE_REF_EX(op1, 2);
}
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) {
op1 = Z_INDIRECT_P(op1);
if (EXPECTED(!Z_ISREF_P(op1))) {
ZVAL_MAKE_REF(op1);
ZVAL_MAKE_REF_EX(op1, 2);
} else {
GC_ADDREF(Z_REF_P(op1));
}
GC_ADDREF(Z_REF_P(op1));
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
} else {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1);
@ -31373,8 +31494,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, &free_op1 EXECUTE_DATA_CC);
@ -31652,10 +31776,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);};
}
@ -33754,10 +33883,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLE
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -35467,10 +35601,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -35603,10 +35742,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -35944,10 +36088,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDL
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -37807,10 +37956,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(Z
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -38461,8 +38615,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(
}
if (EX(return_value)) {
ZVAL_MAKE_REF(retval_ptr);
Z_ADDREF_P(retval_ptr);
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));
}
@ -38613,12 +38770,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_
if (Z_ISREF_P(varptr)) {
Z_ADDREF_P(varptr);
ZVAL_COPY_VALUE(arg, varptr);
} else {
ZVAL_NEW_REF(arg, varptr);
Z_ADDREF_P(arg);
ZVAL_REF(varptr, Z_REF_P(arg));
ZVAL_MAKE_REF_EX(varptr, 2);
}
ZVAL_REF(arg, Z_REF_P(varptr));
ZEND_VM_NEXT_OPCODE();
}
@ -42750,8 +42905,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONS
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@ -43403,10 +43561,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZE
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -43540,12 +43703,8 @@ check_indirect:
}
if (UNEXPECTED(!Z_ISREF_P(value))) {
ref = (zend_reference*)emalloc(sizeof(zend_reference));
GC_SET_REFCOUNT(ref, 2);
GC_TYPE_INFO(ref) = IS_REFERENCE;
ZVAL_COPY_VALUE(&ref->val, value);
Z_REF_P(value) = ref;
Z_TYPE_INFO_P(value) = IS_REFERENCE_EX;
ZVAL_MAKE_REF_EX(value, 2);
ref = Z_REF_P(value);
} else {
ref = Z_REF_P(value);
GC_ADDREF(ref);
@ -46718,8 +46877,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPV
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@ -47316,10 +47478,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -47866,10 +48033,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -48837,8 +49009,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUS
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@ -49305,10 +49480,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(Z
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {
@ -49416,15 +49596,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLE
ZVAL_NULL(Z_REFVAL_P(op1));
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
} else {
ZVAL_MAKE_REF(op1);
ZVAL_COPY(EX_VAR(opline->result.var), op1);
if (Z_ISREF_P(op1)) {
Z_ADDREF_P(op1);
} else {
ZVAL_MAKE_REF_EX(op1, 2);
}
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) {
op1 = Z_INDIRECT_P(op1);
if (EXPECTED(!Z_ISREF_P(op1))) {
ZVAL_MAKE_REF(op1);
ZVAL_MAKE_REF_EX(op1, 2);
} else {
GC_ADDREF(Z_REF_P(op1));
}
GC_ADDREF(Z_REF_P(op1));
ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1));
} else {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1);
@ -52608,8 +52793,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_H
if ((IS_CV == IS_VAR || IS_CV == IS_CV) &&
UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) {
expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC);
ZVAL_MAKE_REF(expr_ptr);
Z_ADDREF_P(expr_ptr);
if (Z_ISREF_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
} else {
ZVAL_MAKE_REF_EX(expr_ptr, 2);
}
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC);
@ -53063,10 +53251,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
(opline->extended_value == ZEND_RETURNS_FUNCTION &&
!Z_ISREF_P(value_ptr)))) {
zend_error(E_NOTICE, "Only variable references should be yielded by reference");
ZVAL_COPY(&generator->value, value_ptr);
} else {
ZVAL_MAKE_REF(value_ptr);
if (Z_ISREF_P(value_ptr)) {
Z_ADDREF_P(value_ptr);
} else {
ZVAL_MAKE_REF_EX(value_ptr, 2);
}
ZVAL_REF(&generator->value, Z_REF_P(value_ptr));
}
ZVAL_COPY(&generator->value, value_ptr);
}
} else {

102
ext/standard/array.c

@ -1763,10 +1763,13 @@ static zend_long php_extract_ref_if_exists(zend_array *arr, zend_array *symbol_t
}
continue;
}
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
ZVAL_REF(orig_var, Z_REF_P(entry));
count++;
}
} ZEND_HASH_FOREACH_END();
@ -1848,13 +1851,19 @@ static zend_long php_extract_ref_overwrite(zend_array *arr, zend_array *symbol_t
if (zend_string_equals_literal(var_name, "GLOBALS")) {
continue;
}
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
ZVAL_REF(orig_var, Z_REF_P(entry));
} else {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
zend_hash_add_new(symbol_table, var_name, entry);
}
count++;
@ -1925,9 +1934,12 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
if (Z_TYPE_P(orig_var) == IS_UNDEF) {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
ZVAL_COPY_VALUE(orig_var, entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
ZVAL_REF(orig_var, Z_REF_P(entry));
count++;
continue;
}
@ -1940,14 +1952,17 @@ static zend_long php_extract_ref_prefix_if_exists(zend_array *arr, zend_array *s
zend_throw_error(NULL, "Cannot re-assign $this");
}
} else {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
ZVAL_REF(orig_var, Z_REF_P(entry));
} else {
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
@ -2034,9 +2049,12 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
if (Z_TYPE_P(orig_var) == IS_UNDEF) {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
ZVAL_COPY_VALUE(orig_var, entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
ZVAL_REF(orig_var, Z_REF_P(entry));
count++;
continue;
}
@ -2049,14 +2067,17 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
zend_throw_error(NULL, "Cannot re-assign $this");
}
} else {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
ZVAL_REF(orig_var, Z_REF_P(entry));
} else {
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
@ -2075,8 +2096,11 @@ static zend_long php_extract_ref_prefix_same(zend_array *arr, zend_array *symbol
}
continue;
}
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
zend_hash_add_new(symbol_table, var_name, entry);
count++;
}
@ -2183,14 +2207,17 @@ static zend_long php_extract_ref_prefix_all(zend_array *arr, zend_array *symbol_
zend_throw_error(NULL, "Cannot re-assign $this");
}
} else {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
ZVAL_REF(orig_var, Z_REF_P(entry));
} else {
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
@ -2286,14 +2313,17 @@ static zend_long php_extract_ref_prefix_invalid(zend_array *arr, zend_array *sym
zend_throw_error(NULL, "Cannot re-assign $this");
}
} else {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
}
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
ZVAL_REF(orig_var, Z_REF_P(entry));
} else {
zend_hash_add_new(symbol_table, Z_STR(final_name), entry);
}
@ -2387,15 +2417,21 @@ static zend_long php_extract_ref_skip(zend_array *arr, zend_array *symbol_table)
if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
orig_var = Z_INDIRECT_P(orig_var);
if (Z_TYPE_P(orig_var) == IS_UNDEF) {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
ZVAL_COPY_VALUE(orig_var, entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
ZVAL_REF(orig_var, Z_REF_P(entry));
count++;
}
}
} else {
ZVAL_MAKE_REF(entry);
Z_ADDREF_P(entry);
if (Z_ISREF_P(entry)) {
Z_ADDREF_P(entry);
} else {
ZVAL_MAKE_REF_EX(entry, 2);
}
zend_hash_add_new(symbol_table, var_name, entry);
count++;
}

Loading…
Cancel
Save