Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:92017 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 3633 invoked from network); 30 Mar 2016 09:34:37 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Mar 2016 09:34:37 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 65.55.169.122 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 65.55.169.122 mail-bl2on0122.outbound.protection.outlook.com Received: from [65.55.169.122] ([65.55.169.122:56480] helo=na01-bl2-obe.outbound.protection.outlook.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id C9/03-24137-BAD9BF65 for ; Wed, 30 Mar 2016 04:34:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=RWSoftware.onmicrosoft.com; s=selector1-zend-com; h=From:To:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=hXoiE+qWZMSFTAcZvmhuRBjohs/4nn02B0umCRH3GD8=; b=24u/pyjKABvFDL55SctiyElOWrzP/O16GbGz8YmaRG+a5L6wGN9Pi6zAlcSVKoUEtkepysyi8WbPr7q4kYowkD83E73cHYMrf+0m1+tISPCNS/1eNrkBIfjlvCzKWr4TItx4pAOzeTWZ8M85r1MRnSF2oSAy/UT6f/CHeOMwA7c= Received: from CY1PR0201MB1786.namprd02.prod.outlook.com (10.163.55.19) by CY1PR0201MB1788.namprd02.prod.outlook.com (10.163.55.21) with Microsoft SMTP Server (TLS) id 15.1.443.12; Wed, 30 Mar 2016 09:34:32 +0000 Received: from CY1PR0201MB1786.namprd02.prod.outlook.com ([10.163.55.19]) by CY1PR0201MB1786.namprd02.prod.outlook.com ([10.163.55.19]) with mapi id 15.01.0447.024; Wed, 30 Mar 2016 09:34:31 +0000 To: Antony Dovgal , Nikita Popov CC: PHP internals Thread-Topic: [PHP-DEV] Forbid binding methods to incompatible $this Thread-Index: AQHRigl+6xTV22juY0yTf1tMtTF7859xuSXt Date: Wed, 30 Mar 2016 09:34:31 +0000 Message-ID: References: In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: lists.php.net; dkim=none (message not signed) header.d=none;lists.php.net; dmarc=none action=none header.from=zend.com; x-originating-ip: [132.245.81.165] x-ms-office365-filtering-correlation-id: ed2deb31-9aa1-4778-ba4d-08d3587e7fa0 x-microsoft-exchange-diagnostics: 1;CY1PR0201MB1788;5:kJkZaOg27cwO5bohplQ27oyj+Ms7SaP4feC5SfBfJnjR/ZdKN+tyDz+VATG4z9DFgL0SpRQQqHk1gWfXkjGlnde+Tf2h6h1cr3h7MfXam9e7xArgoTgoo+GbZjNpBNnqfNbehdj+c6xT5HNElfDCYw==;24:EeIQdrorqTJ8sqp0JX/yI4dZg7iEDnrUza7HNkI0J6lIx94Qx1rVi9aeLc/pbHidf+yQ6KVuzm8t513yQuZJEiXbpDzUUeNco9TVE3vikJ8= x-microsoft-antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0201MB1788; x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:; x-exchange-antispam-report-cfa-test: BCL:0;PCL:0;RULEID:(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046);SRVR:CY1PR0201MB1788;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0201MB1788; x-forefront-prvs: 08978A8F5C x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(979002)(6009001)(87936001)(19273905006)(92566002)(76576001)(15395725005)(99286002)(86362001)(3846002)(122556002)(5004730100002)(5008740100001)(6116002)(33656002)(1220700001)(102836003)(74316001)(1096002)(81166005)(189998001)(106356001)(4326007)(586003)(3900700001)(2906002)(3660700001)(3280700002)(5002640100001)(2950100001)(19580395003)(66066001)(19580405001)(50986999)(76176999)(54356999)(10400500002)(5001770100001)(1720100001)(5003600100002)(15975445007)(2900100001)(77096005)(106116001)(563064011)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1102;SCL:1;SRVR:CY1PR0201MB1788;H:CY1PR0201MB1786.namprd02.prod.outlook.com;FPR:;SPF:None;MLV:ovrnspm;PTR:InfoNoRecords;LANG:en; spamdiagnosticoutput: 1:23 spamdiagnosticmetadata: NSPM Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: zend.com X-MS-Exchange-CrossTenant-originalarrivaltime: 30 Mar 2016 09:34:31.7079 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 32210298-c08b-4829-8097-6b12c025a892 X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR0201MB1788 Subject: Re: [PHP-DEV] Forbid binding methods to incompatible $this From: dmitry@zend.com (Dmitry Stogov) I agree, this ability is a dirty and annoying hack, but I'm sure, some peop= le use it. Tony, you don't use this in the new runkit replacement? :) Thanks. Dmitry. ________________________________________ From: Nikita Popov Sent: Wednesday, March 30, 2016 01:21 To: PHP internals Subject: [PHP-DEV] Forbid binding methods to incompatible $this 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