Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:75161 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 20926 invoked from network); 1 Jul 2014 11:25:22 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Jul 2014 11:25:22 -0000 Authentication-Results: pb1.pair.com header.from=bobwei9@hotmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=bobwei9@hotmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain hotmail.com designates 65.55.111.166 as permitted sender) X-PHP-List-Original-Sender: bobwei9@hotmail.com X-Host-Fingerprint: 65.55.111.166 blu004-omc4s27.hotmail.com Received: from [65.55.111.166] ([65.55.111.166:64536] helo=BLU004-OMC4S27.hotmail.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 33/B1-03359-1AA92B35 for ; Tue, 01 Jul 2014 07:25:22 -0400 Received: from BLU436-SMTP15 ([65.55.111.135]) by BLU004-OMC4S27.hotmail.com with Microsoft SMTPSVC(7.5.7601.22712); Tue, 1 Jul 2014 04:25:19 -0700 X-TMN: [q9ErhpAav8hdu3pdpfO8LIzfI24cVmlI] X-Originating-Email: [bobwei9@hotmail.com] Message-ID: Received: from bobweinandsimac.fritz.box ([88.207.214.175]) by BLU436-SMTP15.smtp.hotmail.com over TLS secured channel with Microsoft SMTPSVC(8.0.9200.16384); Tue, 1 Jul 2014 04:25:17 -0700 Content-Type: multipart/alternative; boundary="Apple-Mail=_6EDF9BA8-B652-4F72-8F14-36D78F2327EE" MIME-Version: 1.0 (Mac OS X Mail 7.3 \(1878.2\)) In-Reply-To: Date: Tue, 1 Jul 2014 13:25:12 +0200 CC: Dmitry Stogov , Andrea Faulds , Xinchen Hui , David Soria Parra , Julien Pauli , PHP Internals References: To: Nikita Popov X-Mailer: Apple Mail (2.1878.2) X-OriginalArrivalTime: 01 Jul 2014 11:25:17.0433 (UTC) FILETIME=[229DDE90:01CF951F] Subject: Re: [PHP-DEV] Wired constant expression syntax and bug From: bobwei9@hotmail.com (Bob Weinand) --Apple-Mail=_6EDF9BA8-B652-4F72-8F14-36D78F2327EE Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="windows-1252" Am 1.7.2014 um 09:12 schrieb Nikita Popov : >=20 > > > > > > > > class FooBar { > > > const bar =3D ["bar" =3D> 3]["bar"]; > > > } > > > > > > It wasn't a part of RFC, it wasn't covered by tests, and it = actually > > > doesn't make a lot of sense. May be it's better to remove it? > > > > I disagree, it makes perfect sense: > > > > class FooBar { > > const FOO =3D 3; > > const BAR =3D [ > > 3 =3D> =91qux=92, > > 4 =3D> =91bang=92, > > 7 =3D> =91theta=92, > > 9 =3D> =91epsilon=92 > > ][FOO]; > > } > > > > ?: and ? only work when there are just two possibilities. > > >=20 > ?: may work with brackets, but I have to admit that it's less = readable. >=20 > class Foo { > const X =3D 2; > const Y =3D (Foo::X =3D=3D 0 ? 1 : > (Foo::X =3D=3D 1 ? 2 : > (Foo::X =3D=3D 2 ? 3 : > (Foo::X =3D=3D 3 ? 4 : > 5)))); > } >=20 > The situation is really inconsistent because we allow expressions on > constant arrays but at the same time prohibit array usage. >=20 > As we support the [..., ...][...] syntax in normal PHP code as well, I = think it's reasonable to allow it here as well. Of course it isn't very = practically useful, but there doesn't seem much point to explicitly = disallowing it here. That's exactly my point. > Look into the following scripts: >=20 >=20 > class Foo { > const BAR =3D [ > 3 =3D> =91qux=92, > 4 =3D> =91bang=92, > 7 =3D> =91theta=92, > 9 =3D> =91epsilon=92 > ][1]; > } > var_dump(Foo::BAR); // works - prints 'bang' > ?> >=20 > class Foo { > const BAR =3D [ > 3 =3D> =91qux=92, > 4 =3D> =91bang=92, > 7 =3D> =91theta=92, > 9 =3D> =91epsilon=92 > ]; > } > var_dump(Foo::BAR); // doesn't work - Fatal error: Arrays are not = allowed > in constants at run-time > ?> >=20 > class Foo { > const BAR =3D [ > 3 =3D> =91qux=92, > 4 =3D> =91bang=92, > 7 =3D> =91theta=92, > 9 =3D> =91epsilon=92 > ]; > } > // This works again! We may declare array class constants if we don't = use > them? > ?> >=20 > Where is the logic? >=20 > The reason here is probably that we cannot detect whether something = will be an array or not until runtime constant updating. E.g. const BAR = =3D FOO ? 1 : [1] or similar. However we might want to detect the case = where an array is the root of the AST, as that is invalid for sure and = the most common case. Not sure if we should check that. That would be adding a new arbitrary = restriction. Now the following works: class Foo { const BAR =3D [ 3 =3D> =91qux=92, 4 =3D> =91bang=92, 7 =3D> =91theta=92, 9 =3D> =91epsilon=92 ]; const BAZ =3D FOO[4]; } var_dump(Foo::BAZ); > Another small issue with the constant expressions I noticed is that = our recursion detection doesn't properly work for constant ASTs. For = example: >=20 > class A { > const FOO =3D [self::BAR]; > const BAR =3D [self::FOO]; > } > var_dump(A::FOO); >=20 > This will result in a stack overflow instead of a fatal error about = self-referencing constants. >=20 > Nikita I think that this is caused by some bugfix for opcache. http://lxr.php.net/xref/PHP_5_6/Zend/zend_ast.c#255 That zval_copy_ctor call duplicates the AST to save it for opcache so = that opcache can store it later. But as that is called before the zend_ast_evaluate, the effects of = MARK_CONSTANT_VISITED() won't affect the contents of the ast (and the = zval with the constant) copied before=85 @Dmitry: Removing this call (and the dtoring in the ast destructor) will = break opcache and fix this bug. How to fix both now? I don't immediately = see a good fix here? Bob= --Apple-Mail=_6EDF9BA8-B652-4F72-8F14-36D78F2327EE--