Hi,

I'm trying to write a function in an extension (using PHP_FUNCTION) that
returns a value by reference. I have declared an arg info block
(ZEND_BEGIN_ARG_INFO_EX) to tell the engine that I am returning a value
by reference. Then to return the value, I first delete the old return
value (zval_ptr_dtor(&return_value)), and then overwrite
*return_value_ptr. This seems to work if the function is called from PHP.

However, when I try to call the function manually from another extension
function (using call_user_function_ex), things break. After
call_user_function_ex returns, I do get the right zval pointer, but its
refcount and is_ref fields have been reset to 1 and 0. After some
debugging it turned out that is this due to zend_call_function (in
zend_execute_API.c). The relevant snippet is:

    if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
      // ...
    } else {
        ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
        if (EX(function_state).function->common.scope) {
            EG(scope) = EX(function_state).function->common.scope;
        }
        ((zend_internal_function *) 
EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, 
EX(function_state).function->common.return_reference?fci->retval_ptr_ptr:NULL, 
(fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
        INIT_PZVAL(*fci->retval_ptr_ptr);
    }

(in 5.2.2, line 982 and following). Note the last line in that else:
after the function has been called, INIT_PZVAL is called on the return
value of the function, overriding whatever refcount and is_ref I had set
for the zval to be returned.

How do I solve this problem?

Thanks!

Edsko 

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

Reply via email to