I've got a one-line fix to allow internal functions to return by reference.

What happens currently is if (*return_value_ptr)->refcount <= 2 at the end
of an internal function, then the _get_zval_ptr_ptr_var delrefs it down to
refcount==1 (removing is_ref in the process).  With userspace functions
ASSIGN_REF can handle this since
EX_T(opline->result.u.var).var.fcall_returned_reference is set appropriately
in fcall_common_helper.  With internal functions, this value is never set.

The following one-liner change to Zend/zend_vm_def.h sets this value if the
function has declared itself to return reference (based on arg_info data),
and the value in return_value_ptr is in fact set to is_ref.

Two question: (1) Is it okay for me to just commit this (Andi? Zeev?), (2)
Should this fix be applied to 5.1 and 5.0 branches as well?  Note: It
doesn't directly apply to 4.x branches since they have no return_value_ptr,
nor arg_info hinting.  I havn't actually looked at the PHP_4_4 branch to see
if it has a similar problem.

-Sara

Index: zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.68
diff -u -r1.68 zend_vm_def.h
--- zend_vm_def.h       19 Aug 2005 13:20:14 -0000      1.68
+++ zend_vm_def.h       23 Aug 2005 18:38:28 -0000
@@ -1883,6 +1883,8 @@
                        EX_T(opline->result.u.var).var.ptr->refcount = 1;
                }
 */
+               EX_T(opline->result.u.var).var.fcall_returned_reference =
EX(function_state).function->common.return_reference &&
EX_T(opline->result.u.var).var.ptr->is_ref;
+
                if (!return_value_used) {
                        zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
                }

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to