diff options
author | Andi Gutmans <andi@php.net> | 1999-12-11 12:14:21 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 1999-12-11 12:14:21 +0000 |
commit | 0e2f4cc32645885fd9de086732efff3fd84bfe98 (patch) | |
tree | abb1380b03f4301bea3a6e4aa5dcaf727b0eff9b | |
parent | 3ebf98f1489b012ac6d2d39c84909beafe79adeb (diff) | |
download | php-git-0e2f4cc32645885fd9de086732efff3fd84bfe98.tar.gz |
- Support returning references
-rw-r--r-- | Zend/zend_execute.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index a2d8d30feb..c7a7924343 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -378,7 +378,7 @@ static inline void zend_assign_to_variable(znode *result, znode *op1, znode *op2 */ /* break missing intentionally */ case IS_CONST: - if (PZVAL_IS_REF(value)) { + if (PZVAL_IS_REF(value) && value->refcount > 0) { variable_ptr = *variable_ptr_ptr = (zval *) emalloc(sizeof(zval)); *variable_ptr = *value; zval_copy_ctor(variable_ptr); @@ -1544,17 +1544,36 @@ do_fcall_common: } break; case ZEND_RETURN: { - zval *retval = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); + zval *retval_ptr; + zval **retval_ptr_ptr; - if (!EG(free_op1)) { /* Not a temp var */ + if (opline->extended_value) { + retval_ptr_ptr = get_zval_ptr_ptr(&opline->op1, Ts, BP_VAR_R); + SEPARATE_ZVAL(retval_ptr_ptr); + (*retval_ptr_ptr)->is_ref = 1; + (*retval_ptr_ptr)->refcount++; efree(*EG(return_value_ptr_ptr)); - /* Still need to check for reference */ - *EG(return_value_ptr_ptr) = retval; - retval->refcount++; + (*EG(return_value_ptr_ptr)) = (*retval_ptr_ptr); } else { - **EG(return_value_ptr_ptr) = *retval; - (*EG(return_value_ptr_ptr))->refcount = 1; - (*EG(return_value_ptr_ptr))->is_ref = 0; + retval_ptr = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R); + + if (!EG(free_op1)) { /* Not a temp var */ + + if (PZVAL_IS_REF(retval_ptr) && retval_ptr->refcount > 0) { + **EG(return_value_ptr_ptr) = *retval_ptr; + (*EG(return_value_ptr_ptr))->is_ref = 0; + (*EG(return_value_ptr_ptr))->refcount = 1; + zval_copy_ctor(*EG(return_value_ptr_ptr)); + } else { + efree(*EG(return_value_ptr_ptr)); + *EG(return_value_ptr_ptr) = retval_ptr; + retval_ptr->refcount++; + } + } else { + **EG(return_value_ptr_ptr) = *retval_ptr; + (*EG(return_value_ptr_ptr))->refcount = 1; + (*EG(return_value_ptr_ptr))->is_ref = 0; + } } #if SUPPORT_INTERACTIVE op_array->last_executed_op_number = opline-op_array->opcodes; |