Skip to content

Commit 0e2f4cc

Browse files
author
Andi Gutmans
committed
- Support returning references
1 parent 3ebf98f commit 0e2f4cc

File tree

1 file changed

+28
-9
lines changed

1 file changed

+28
-9
lines changed

Zend/zend_execute.c

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2
378378
*/
379379
/* break missing intentionally */
380380
case IS_CONST:
381-
if (PZVAL_IS_REF(value)) {
381+
if (PZVAL_IS_REF(value) && value->refcount > 0) {
382382
variable_ptr = *variable_ptr_ptr = (zval *) emalloc(sizeof(zval));
383383
*variable_ptr = *value;
384384
zval_copy_ctor(variable_ptr);
@@ -1544,17 +1544,36 @@ binary_assign_op_addr: {
15441544
}
15451545
break;
15461546
case ZEND_RETURN: {
1547-
zval *retval = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
1547+
zval *retval_ptr;
1548+
zval **retval_ptr_ptr;
15481549

1549-
if (!EG(free_op1)) { /* Not a temp var */
1550+
if (opline->extended_value) {
1551+
retval_ptr_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R);
1552+
SEPARATE_ZVAL(retval_ptr_ptr);
1553+
(*retval_ptr_ptr)->is_ref = 1;
1554+
(*retval_ptr_ptr)->refcount++;
15501555
efree(*EG(return_value_ptr_ptr));
1551-
/* Still need to check for reference */
1552-
*EG(return_value_ptr_ptr) = retval;
1553-
retval->refcount++;
1556+
(*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr);
15541557
} else {
1555-
**EG(return_value_ptr_ptr) = *retval;
1556-
(*EG(return_value_ptr_ptr))->refcount = 1;
1557-
(*EG(return_value_ptr_ptr))->is_ref = 0;
1558+
retval_ptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
1559+
1560+
if (!EG(free_op1)) { /* Not a temp var */
1561+
1562+
if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) {
1563+
**EG(return_value_ptr_ptr) = *retval_ptr;
1564+
(*EG(return_value_ptr_ptr))->is_ref = 0;
1565+
(*EG(return_value_ptr_ptr))->refcount = 1;
1566+
zval_copy_ctor(*EG(return_value_ptr_ptr));
1567+
} else {
1568+
efree(*EG(return_value_ptr_ptr));
1569+
*EG(return_value_ptr_ptr) = retval_ptr;
1570+
retval_ptr->refcount++;
1571+
}
1572+
} else {
1573+
**EG(return_value_ptr_ptr) = *retval_ptr;
1574+
(*EG(return_value_ptr_ptr))->refcount = 1;
1575+
(*EG(return_value_ptr_ptr))->is_ref = 0;
1576+
}
15581577
}
15591578
#if SUPPORT_INTERACTIVE
15601579
op_array->last_executed_op_number = opline-op_array->opcodes;

0 commit comments

Comments
 (0)