Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92015 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 285 invoked from network); 30 Mar 2016 09:29:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Mar 2016 09:29:09 -0000 Authentication-Results: pb1.pair.com smtp.mail=t.carnage@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=t.carnage@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.217.178 as permitted sender) X-PHP-List-Original-Sender: t.carnage@gmail.com X-Host-Fingerprint: 209.85.217.178 mail-lb0-f178.google.com Received: from [209.85.217.178] ([209.85.217.178:32813] helo=mail-lb0-f178.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B7/42-24137-36C9BF65 for ; Wed, 30 Mar 2016 04:29:08 -0500 Received: by mail-lb0-f178.google.com with SMTP id u8so27748906lbk.0 for ; Wed, 30 Mar 2016 02:29:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc; bh=sa1VaQZTp4WMKGZQHRj7OFCDZT67KauAeWBOdCx76CU=; b=ojOrSB9q3yhSPu3FDBAW4nme7Ob9gNnVNLGBMB5DycCUj18o1z4W0XyCWb/XHtpqhu Yd1FKxUQo7Pp7BujIhlfAtZrtY4PoTNsF4AjgnldpND+XFlYPNtdg3nAsL0rZdxC8BGE kpHxl90wGE1xyOxwRUsmSZvIFJ0SDYE6JG+iM5uncCyYD0h/384Ir/7jh3rvxGSgbMxX CQwbCh3wC6PeivFagfNJa+dct3qZ1KhoJCS3GQjyHmSpiZrBszrYhz0pKGyDBr8LFdG4 Ly2xNxLQpIZW72+nZocH/Qpc3yHjgd+qsighXT1l5rOddi4ErwIEz8pCeuMGjJ70bBBL iJXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc; bh=sa1VaQZTp4WMKGZQHRj7OFCDZT67KauAeWBOdCx76CU=; b=UmMXqoO81nz3vRv6uwcFncSVaqrhMWRkxKaaN4zJKlt9w8Pi5yIQRjvjdxeLMqlhYS QuSi4U9je3eO5CIRu4ZTIDkAzm6r6VSmTGCUvUjlhfsuG9K+4LgIFpKTiMTn8Loj//ak aqzHx74v4qGUGUWX2XBxXn12YH1AfaX+qSyyI/Ss7v5keUDqaVM7VZ52UmBwgNHWVpNC g5idaVdOFmJrPF5clh3d0hjGoOb99Dg2uhTDAWOjbL5AqFLi5jYMyuy/tlAdvBlKI0IA 5b7bAR9gGi81Ait9aeF4ZWE9+OvQCfozwACue4WI8FcXpRRftwaxVf5i8mnyHoz3KVCm ZDsw== X-Gm-Message-State: AD7BkJLB79kXrmAc+6FrYLp+A+A+Eg2UVe7/X5+sNkAJffacKCqw1m/CbymfiKGrN6D+KIRA+joeGBxx5eyixQ== MIME-Version: 1.0 X-Received: by 10.112.16.230 with SMTP id j6mr3292300lbd.27.1459330145013; Wed, 30 Mar 2016 02:29:05 -0700 (PDT) Received: by 10.112.0.200 with HTTP; Wed, 30 Mar 2016 02:29:04 -0700 (PDT) In-Reply-To: References: Date: Wed, 30 Mar 2016 10:29:04 +0100 Message-ID: To: Nikita Popov Cc: PHP internals Content-Type: multipart/alternative; boundary=001a11c3c6d2e75535052f40c6a8 Subject: Re: [PHP-DEV] Forbid binding methods to incompatible $this From: t.carnage@gmail.com (Chris Riley) --001a11c3c6d2e75535052f40c6a8 Content-Type: text/plain; charset=UTF-8 On 29 March 2016 at 23:21, Nikita Popov wrote: > Hi internals! > > Currently, inside instance methods the following invariant holds: > > assert(is_null($this) || is_object($this)) > > This is a problem. I'd like to guarantee the following invariant instead: > > assert(is_null($this) || $this instanceof self) > > That is, ensure that if $this is not null, then it must be an object > "compatible" with the class, i.e. be in its inheritance hierarchy. > > The absence of this guarantee, apart from being a major WTF in itself, also > prevents us from optimizing operations involving $this. In particular, the > following optimizations are not possible: > > a) If typed properties land, we will not be able to use the type of > $this->typedProperty for optimization, because $this->typedProperty might > actually be referencing a property of a totally unrelated class. > b) We are not able to early-bind arguments to private or final method > calls, i.e. determine at compile-time whether an argument will use by-value > or by-reference argument passing and optimize accordingly. > c) We are not able to inline calls to private or final methods. (The > possibility of null is an issue in this instance as well, though a lesser > one.) > > The good news is that, as of PHP 7.0, we are *very* close to guaranteeing > that "$this instanceof self" already. There exists only one little known > loophole: Obtaining a closure object wrapping the method using > ReflectionMethod::getClosure() and binding to an unrelated $this using > Closure::bindTo(). > > In PHP 7.0 we already heavily cut down [1] on what bindTo() is to allowed > to do on fake method closures. Namely, it was completely forbidden to > rebind the scope of methods, as this was already interacting badly with > optimizations in 7.0. We did not forbid binding to an incompatible $this > because it was not yet causing immediate issues at the time. > > I'd like to remedy this oversight now and restrict $this binding of fake > method closures to compatible contexts only, i.e. for a method A::foo() > allow only instances of A or one of its descendant classes to be bound. > This limitation already exists for fake method closures targeting internal > methods. > > Are there any objections to this change? If not, I'll merge the patch [2]. > If yes, I'll write an RFC, as this change, while of no direct consequence > for PHP programmers, is important for the PHP implementation. > > Regards, > Nikita > > [1]: http://markmail.org/message/sjihplebuwsmdwex > [2]: > https://github.com/php/php-src/compare/master...nikic:forbigIncompatThis > Hi, Will this patch break any use cases similar to: class Bar { private $a = 'hidden'; } $x = new Bar(); $y = function() { return $this->a); $z = $x->bindTo($x, $x); echo $z(); //hidden ? If not, I have no objections. --001a11c3c6d2e75535052f40c6a8--