Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92150 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 67510 invoked from network); 7 Apr 2016 22:43:26 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Apr 2016 22:43:26 -0000 Authentication-Results: pb1.pair.com header.from=nikita.ppv@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=nikita.ppv@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.161.177 as permitted sender) X-PHP-List-Original-Sender: nikita.ppv@gmail.com X-Host-Fingerprint: 209.85.161.177 mail-yw0-f177.google.com Received: from [209.85.161.177] ([209.85.161.177:35392] helo=mail-yw0-f177.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 97/67-48788-B52E6075 for ; Thu, 07 Apr 2016 18:42:35 -0400 Received: by mail-yw0-f177.google.com with SMTP id i84so108894345ywc.2 for ; Thu, 07 Apr 2016 15:42:35 -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; bh=Qbg+Vu1Uv80x5Dy+NHjZqJq8Y1YSNqGjmt65cUWKBww=; b=TOE4rO+q5UiucmR+dk/1s+cKQZPqPc2Cm5sZ7RceVNQZpAjgoB0ymRtQohDKK/uGbp 2rYXjvOJeVefxYTA6OshhGE5vKn5bZDHeS/PB1RQnOwD0fu4SfNVPHvzLS59X7ck2It1 kZtel0e2+eyVK0wqkvQLrwwLngLog+nFJ8pbRfxBkMoyj6BPZbOiwaR3ijF6++AbD8Hr 2zOMzpZEDNEjk70/i7OD4OcS1qs/MuhCZI4ZR866uhpG5iKsrisfqOO6RxwbiamoQuZT usnUpZLFb5UQEGjFDNU1+3vojtoLW7M3cjv1WJAyUBUS9DE/WnvahDuLVUUiAD+SLESp v0oQ== 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; bh=Qbg+Vu1Uv80x5Dy+NHjZqJq8Y1YSNqGjmt65cUWKBww=; b=SfkrQ/jlSA9pJPE4fDIe9zU3NZNAn5ZDktGpLUqt7Y7fpvnnRQoMC+Fj5RBdwW9TKi lCNva5srxKU4Et6xL5VNTHsiJ+j/l97PzuiXQ36lftzrjMGt8ro0GveFiCjmtFidxyzX DfRXVSqwbE3qTDHEO4YetMXad058o9HF5Pkvf0buqqBBVWcCFiWjQ3NdkniVX7qA0TiB wqeTJ9eqcswU9GPfDh+ANEL3bHDIhJnxRN+PJ8aSeVkrI5SBCLuTSRjmJVSidCcyeA/V O7+10IOqRcJ3vuDURQQrZ1ekaQ0g7W1M51Qrq6LOwLqv8wW6LOt3EURkAVRSi/WGeWSf oNdg== X-Gm-Message-State: AD7BkJKt698UoREGIyzvnbfi0lMEhOxQkB2+QQwXk0WiMDzIJ6v7mQ6zZHTdzChcKwM8sp+u+Dc3PysIWP6d7w== MIME-Version: 1.0 X-Received: by 10.129.31.131 with SMTP id f125mr3108134ywf.267.1460068953105; Thu, 07 Apr 2016 15:42:33 -0700 (PDT) Received: by 10.129.148.70 with HTTP; Thu, 7 Apr 2016 15:42:33 -0700 (PDT) In-Reply-To: References: Date: Fri, 8 Apr 2016 07:42:33 +0900 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary=001a1141e7f44c2a3d052feccbb5 Subject: Re: Forbid binding methods to incompatible $this From: nikita.ppv@gmail.com (Nikita Popov) --001a1141e7f44c2a3d052feccbb5 Content-Type: text/plain; charset=UTF-8 On Wed, Mar 30, 2016 at 7:21 AM, 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 > As the discussion was positive, this is now merged as https://github.com/php/php-src/commit/75af8150f58fb55637ac12b33d469b27adef9d76 . Nikita --001a1141e7f44c2a3d052feccbb5--