Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:29997 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 70544 invoked by uid 1010); 31 May 2007 11:03:14 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 70529 invoked from network); 31 May 2007 11:03:14 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 31 May 2007 11:03:14 -0000 Authentication-Results: pb1.pair.com header.from=devriese@cs.tcd.ie; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=edsko@netsoc.tcd.ie; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain netsoc.tcd.ie from 134.226.83.42 cause and error) X-PHP-List-Original-Sender: edsko@netsoc.tcd.ie X-Host-Fingerprint: 134.226.83.42 spoon.netsoc.tcd.ie Linux 2.6 Received: from [134.226.83.42] ([134.226.83.42:33112] helo=spoon.netsoc.tcd.ie) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 22/E7-13361-07BAE564 for ; Thu, 31 May 2007 07:03:13 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by spoon.netsoc.tcd.ie (Postfix) with ESMTP id 8CB19544F4 for ; Thu, 31 May 2007 12:03:09 +0100 (IST) Received: from spoon.netsoc.tcd.ie ([127.0.0.1]) by localhost (spoon.netsoc.tcd.ie [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 32060-10 for ; Thu, 31 May 2007 12:03:09 +0100 (IST) Received: by spoon.netsoc.tcd.ie (Postfix, from userid 1025) id 655B6546BC; Thu, 31 May 2007 12:03:09 +0100 (IST) Date: Thu, 31 May 2007 12:03:09 +0100 To: internals@lists.php.net Message-ID: <20070531110309.GA9827@netsoc.tcd.ie> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Operating-System: Linux spoon.netsoc.tcd.ie 2.6.17 User-Agent: Mutt/1.5.9i X-Virus-Scanned: by amavisd-new-20030616-p10 (Debian) at spoon.netsoc.tcd.ie Subject: Returning by reference From: devriese@cs.tcd.ie (Edsko de Vries) 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