[PHP-DEV] Returning References from Internal Functions

2005-08-23 Thread Sara Golemon
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 -  1.68
+++ zend_vm_def.h   23 Aug 2005 18:38:28 -
@@ -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



Re: [PHP-DEV] Returning References from Internal Functions

2005-08-23 Thread Andi Gutmans
We'll take a look at it as this should actually work today. As to 
back porting, I don't think we should touch the stable branches.


Andi

At 11:47 AM 8/23/2005, Sara Golemon wrote:

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 -  1.68
+++ zend_vm_def.h   23 Aug 2005 18:38:28 -
@@ -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


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



Re: [PHP-DEV] Returning References from Internal Functions

2005-08-23 Thread Sara Golemon
> We'll take a look at it as this should actually work today.
>
That's what I'd thought coming into this, but all my attempts to return a
reference failed:

My Arg Info struct:
static
ZEND_BEGIN_ARG_INFO_EX(php_sample_retref_arginfo, 0, 1, 0)
ZEND_END_ARG_INFO()

My reference linking:
if (return_value_ptr) {
zval_ptr_dtor(return_value_ptr);
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(&val);
ZVAL_ADDREF(val);
*return_value_ptr = val;



There's some commented out code in there that refers to bug 34045:
/*  We shouldn't fix bad extensions here,
because it can break proper ones (Bug #34045)
if (!EX(function_state).function->common.return_reference) {
EX_T(opline->result.u.var).var.ptr->is_ref = 0;
EX_T(opline->result.u.var).var.ptr->refcount = 1;
}
*/

With that code in there returning references would certainly never work so
I'd be curious about the events leading up to that removal as much as
anything.

> As to back porting, I don't think we should touch the stable branches.
>
Eh, it's a 50/50 on this one since the bug only effects internals code and
(last I checked) there's nothing internal that's trying to return a
reference other that OOP code (because it gets shoved into being a reference
anyway).  I only came across this because I was trying to come up with some
example code "If you wanted to do this you could...".

I know I personally would like to see it work in 5.1 at the least (being shy
of final such as we are...).  As for 5.0... yeah let's sleeping dogs lie.

-Sara

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



Re: [PHP-DEV] Returning References from Internal Functions

2005-08-23 Thread Andi Gutmans

OK thanks for the additional info. Will take a look.

At 05:05 PM 8/23/2005, Sara Golemon wrote:

> We'll take a look at it as this should actually work today.
>
That's what I'd thought coming into this, but all my attempts to return a
reference failed:

My Arg Info struct:
static
ZEND_BEGIN_ARG_INFO_EX(php_sample_retref_arginfo, 0, 1, 0)
ZEND_END_ARG_INFO()

My reference linking:
if (return_value_ptr) {
zval_ptr_dtor(return_value_ptr);
}
SEPARATE_ZVAL_TO_MAKE_IS_REF(&val);
ZVAL_ADDREF(val);
*return_value_ptr = val;



There's some commented out code in there that refers to bug 34045:
/*  We shouldn't fix bad extensions here,
because it can break proper ones (Bug #34045)
if (!EX(function_state).function->common.return_reference) {
EX_T(opline->result.u.var).var.ptr->is_ref = 0;
EX_T(opline->result.u.var).var.ptr->refcount = 1;
}
*/

With that code in there returning references would certainly never work so
I'd be curious about the events leading up to that removal as much as
anything.

> As to back porting, I don't think we should touch the stable branches.
>
Eh, it's a 50/50 on this one since the bug only effects internals code and
(last I checked) there's nothing internal that's trying to return a
reference other that OOP code (because it gets shoved into being a reference
anyway).  I only came across this because I was trying to come up with some
example code "If you wanted to do this you could...".

I know I personally would like to see it work in 5.1 at the least (being shy
of final such as we are...).  As for 5.0... yeah let's sleeping dogs lie.

-Sara


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



Re: [PHP-DEV] Returning References from Internal Functions

2005-08-23 Thread Sara Golemon
> There's some commented out code in there that refers to bug 34045:
> /*  We shouldn't fix bad extensions here,
> because it can break proper ones (Bug #34045)
> if (!EX(function_state).function->common.return_reference) {
> EX_T(opline->result.u.var).var.ptr->is_ref = 0;
> EX_T(opline->result.u.var).var.ptr->refcount = 1;
> }
> */
>
> With that code in there returning references would certainly never work so
> I'd be curious about the events leading up to that removal as much as
> anything.
>
Doi... Ignore that particular comment.  All that code does is block
reference passing when the arg info isn't set.  (Which would seem perfectly
reasonable...)

The rest of it still stands, I just spent too long unfolding engine code
today decoding the fcall_returned_reference logic... :)

-Sara

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



RE: [PHP-DEV] Returning References from Internal Functions

2005-08-24 Thread Dmitry Stogov
Thank you Sara.
Now the bug is fixed in PHP_5_1 and HEAD.
The test is in attachment.

Dmitry.

> -Original Message-
> From: Sara Golemon [mailto:[EMAIL PROTECTED] 
> Sent: Wednesday, August 24, 2005 4:47 AM
> To: internals@lists.php.net
> Cc: Andi Gutmans
> Subject: Re: [PHP-DEV] Returning References from Internal Functions
> 
> 
> > There's some commented out code in there that refers to bug 34045:
> > /*  We shouldn't fix bad extensions here,
> > because it can break proper ones (Bug #34045)
> > if (!EX(function_state).function->common.return_reference) {
> > EX_T(opline->result.u.var).var.ptr->is_ref = 0;
> > EX_T(opline->result.u.var).var.ptr->refcount = 1;
> > }
> > */
> >
> > With that code in there returning references would certainly never 
> > work so I'd be curious about the events leading up to that 
> removal as 
> > much as anything.
> >
> Doi... Ignore that particular comment.  All that code does is 
> block reference passing when the arg info isn't set.  (Which 
> would seem perfectly
> reasonable...)
> 
> The rest of it still stands, I just spent too long unfolding 
> engine code today decoding the fcall_returned_reference logic... :)
> 
> -Sara
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 
> 


retref.tar.gz
Description: GNU Zip compressed data
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php