Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:70453 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 69217 invoked from network); 30 Nov 2013 09:34:34 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Nov 2013 09:34:34 -0000 Authentication-Results: pb1.pair.com smtp.mail=ellison.terry@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ellison.terry@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.47 as permitted sender) X-PHP-List-Original-Sender: ellison.terry@gmail.com X-Host-Fingerprint: 74.125.82.47 mail-wg0-f47.google.com Received: from [74.125.82.47] ([74.125.82.47:52299] helo=mail-wg0-f47.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 02/00-03478-921B9925 for ; Sat, 30 Nov 2013 04:34:34 -0500 Received: by mail-wg0-f47.google.com with SMTP id n12so8890117wgh.2 for ; Sat, 30 Nov 2013 01:34:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type; bh=+lq12sAS1wr8ET4DFn+sBaZyAuxormxb55zJVt6ugos=; b=uAe/mThwtT8TRshyqEpMbWTAR9O2VDxuUaE55KWyh7sj5hsaC0Mwozt3Fofg5rXg2z I8dLjrwavuy9hvD6iyqlCM5s9ONrC0cL3LCpvXLwcky3m0qMNzly+p32lk0uF46v2FYz U9flkK+BpIjn4WRYNuK36p8N4WvKPEAEKX2oE1Q+HovhMqY2iHwWbkrrzTzeSlLFcag0 bYzDNysFI4e6399YLe3iU4ltqVCvajYUF/y++WZJCdspkPU0LqXDO/1byJ4oi0TDs0h5 SXopHceHFffR4c+EMjiJXy7AU2u8igFgSP17FVeRN+N3fCdBQspU8HEtbwB5ehw3DlgP 0J4g== X-Received: by 10.194.175.133 with SMTP id ca5mr44449115wjc.19.1385804070242; Sat, 30 Nov 2013 01:34:30 -0800 (PST) Received: from [192.168.1.91] (host81-152-194-204.range81-152.btcentralplus.com. [81.152.194.204]) by mx.google.com with ESMTPSA id c10sm100090103wie.11.2013.11.30.01.34.29 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 30 Nov 2013 01:34:29 -0800 (PST) Message-ID: <5299B124.3030809@gmail.com> Date: Sat, 30 Nov 2013 09:34:28 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.1 MIME-Version: 1.0 To: Stas Malyshev , PHP Internals CC: Joe Watkins , "arjen@react.com" , Ferenc Kovacs References: <528CE64A.1020303@gmail.com> <528EA006.2090400@gmail.com> <52993190.4010905@gmail.com> <52995F97.7000901@sugarcrm.com> In-Reply-To: <52995F97.7000901@sugarcrm.com> Content-Type: multipart/alternative; boundary="------------070104030601050801040307" Subject: Re: [PHP-DEV] Comments on non-unique naming convention for closures From: ellison.terry@gmail.com (Terry Ellison) --------------070104030601050801040307 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 30/11/13 03:46, Stas Malyshev wrote: >> Having discussed the options with Dmitry and another contributor off PHP >> Internals list, we have decided to base the generated >> function name on a hash of the source content between the text pointers > Wouldn't that imply that two closures with the same code would be > identified as the same closure? If so, I'm not sure this is a correct > approach - one can definitely have two different closures (with > different states, different bindings, etc.) having same source text. Or > am I missing something here? > Stas, nope, not quite. The compiler generates a zend_function oparray for each closure that it compiles at *compile time*, and stores this in the execution function table under a mangled name. It also generates a ZEND_DECLARE_LAMBDA_FUNCTION instruction at the appropriate place in the oparray referencing the closure. When *executed*, this acts as the CTOR for the closure object and this deep copies the dummy mangled zend_function entry into the closure object. It is this entry within the closure object that is in fact executed when the closure is invoked. The use bindings take place as part of the CTOR. This copy is then GCed at the closure DTOR. So the CTOR will occur each time the ZEND_DECLARE_LAMBDA_FUNCTION is executed, and the DTORs occur in line with normal PHP scoping / GC rules. This bug is that the current mangling rules mean that under some perverse (but possible in real life) conditions, two different source codes could generate the same mangled name so the second entry would incorrectly override the first, resulting in the closure CTORs binding the wrong function, so we need a unique mangling algo. The mangled zend_function entry is never executed; only used as a copy template. A simple sequence count of the number of closures compiled this request would be fine to separate closure declarations and guarantee uniqueness -- except when OPcaching is involved, so some context dependent hash i needed. This is really a separate thread, but in order to allow opcode caching, the PHP compiler *must* generate the same oparray for a given source sequence, so in fact even if the same function (...) {...} text sequence occured multiple times in the same source file, then the oparrays would be identical anyway, and using the same mangled zend_function entry is fine. However, if the 1/2^64 (or thereabouts) chance of a false collision is unacceptable, we could always embed the closure compile count in the name as well, or the microsecond compile time. Hope this explanation helps :-) Terry --------------070104030601050801040307--