Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:75929 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 86740 invoked from network); 23 Jul 2014 08:47:40 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 23 Jul 2014 08:47:40 -0000 Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 209.85.220.181 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 209.85.220.181 mail-vc0-f181.google.com Received: from [209.85.220.181] ([209.85.220.181:56062] helo=mail-vc0-f181.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 65/81-21666-AA67FC35 for ; Wed, 23 Jul 2014 04:47:39 -0400 Received: by mail-vc0-f181.google.com with SMTP id lf12so1525968vcb.26 for ; Wed, 23 Jul 2014 01:47:37 -0700 (PDT) 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:content-type; bh=ywtG0gS02TRBryvaQ0dHusp3efq6yJ0nMwl5vgZxyqg=; b=fdIEPfbl/bPbSdQjrCKLHhQ0bkBRm6GitjvfgalzXZDwqZB1JetgXudONFAK0IMUzt /CuS2Ytbm5vdx+G/neL4icoevBFeebe/nA+FZpO3KgCYSrDdQ7lGzkOPJuEx7ZHL0oD1 vSYaJMpgiHjfNDoVOKpG4A8ZnQYu7uhSg4wqaxBo42iMlnp0yURm+qSg/wuUMAHtE4kI Ltno8Ud0rRFOShc3lB4Yeykr8q8biuzF5I7CFAmNk5n4cI5y4ACZw9VgTOdg4tjRqi5e 16KVDzyYwD29YpwGcgR39x2nppQCxLrtm7YtUPRHNQmQKzz/wfrkWUm497nvajs5tBzX j+jQ== X-Gm-Message-State: ALoCoQnh0fumCaENbDEzJsEmW3I//Cb8hNK+BMypV3o1tLuSEf503QR2XZZeoW4heWvaWOeDqkR0MADeKsQr8iEaamfff1zP+ih0+9i8HpBH7VWi4Rc0/pvEqNguqUfaMiw3phIXv9/b MIME-Version: 1.0 X-Received: by 10.52.113.37 with SMTP id iv5mr30535736vdb.51.1406105257016; Wed, 23 Jul 2014 01:47:37 -0700 (PDT) Received: by 10.52.110.170 with HTTP; Wed, 23 Jul 2014 01:47:36 -0700 (PDT) In-Reply-To: References: Date: Wed, 23 Jul 2014 12:47:36 +0400 Message-ID: To: Bob Weinand Cc: Nikita Popov , Stas Malyshev , Julien Pauli , PHP Internals Content-Type: multipart/alternative; boundary=bcaec548a8f75c99e804fed864f6 Subject: Re: [PHP-DEV] Weird constant expression syntax and bug From: dmitry@zend.com (Dmitry Stogov) --bcaec548a8f75c99e804fed864f6 Content-Type: text/plain; charset=UTF-8 On Wed, Jul 23, 2014 at 12:16 PM, Bob Weinand wrote: > Hey, thank you for looking into it :-) > > Am 23.7.2014 um 00:23 schrieb Dmitry Stogov : > > hi Bob, > > > > I still think that current array usage in constant expressions is not > > consistent and dangerous. It "smells" to me, and I think it may bring > > troubles in the future even if the existing known bugs are fixed. > > > > I see few issues: > > > > 1) It is possible to declare array class constants however they can't be > > used. I can't remember why array in constants were prohibited before and > > what problems they brought. The following script works without any > warnings. > > > > > class Foo { > > const BAR = [1]; > > } > > ?> > > Because it's actually valid. You don't use it in non-static scalar context. > > > 2) In some cases array constants may be used, but not in the others. > > > > > class Foo { > > const BAR = [0]; > > static $a = Foo::BAR; // constant array usage > > } > > var_dump(Foo::$a); // prints array > > var_dump(Foo::BAR); // emits fatal error > > ?> > > They can only be used in static scalar contexts. > > I wanted to introduce constants to be used and dereferenced also at > run-time, but that requires a RFC. > If anyone would allow me to introduce that still now (it'd be a relatively > simple patch), I'll happily do it. > The issue just was that I was a bit late to create a RFC (beta freeze > etc...) > > > 3) The fact that constants are allowed in compile time and even stored, > but > > can't be used confuses me as well as the error message "PHP Fatal error: > > Arrays are not allowed in constants at run-time". > > See above... > Yeah all the issues above (1-3) are actually a single inconsistency. You may find it logical, but I think differently. > > > 4) Zend/tests/constant_expressions_arrays.phpt crashes whit > > opcache.protect_memory=1 (that indicates petential SHM memory corruption) > > > > This may be fixed with the following patch: > > > > diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h > > index 144930e..f1aab9a 100644 > > --- a/Zend/zend_vm_execute.h > > +++ b/Zend/zend_vm_execute.h > > @@ -4323,6 +4323,16 @@ static int ZEND_FASTCALL > > ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD > > c.value = *tmp_ptr; > > } else { > > INIT_PZVAL_COPY(&c.value, val); > > + if (Z_TYPE(c.value) == IS_ARRAY) { > > + HashTable *ht; > > + > > + ALLOC_HASHTABLE(ht); > > + zend_hash_init(ht, > > zend_hash_num_elements(Z_ARRVAL(c.value)), NULL, ZVAL_PTR_DTOR, 0); > > + zend_hash_copy(ht, Z_ARRVAL(c.value), > > (copy_ctor_func_t) zval_deep_copy, NULL, sizeof(zval *)); > > + Z_ARRVAL(c.value) = ht; > > + } else { > > + zval_copy_ctor(&c.value); > > + } > > zval_copy_ctor(&c.value); > > } > > c.flags = CONST_CS; /* non persistent, case sensetive */ > > I assume you wanted to patch zend_vm_def.h, not zend_vm_execute.h. > Yes. Of course. > If you can fix it, please apply the patch, I'm not so deep into opcache to > take responsibility for that one. > OK. This part of the patch must be safe. I'll apply it later. > > > 5) Circular constant references crash (found by Nikita) > > > > > class A { > > const FOO = [self::BAR]; > > const BAR = [self::FOO]; > > } > > var_dump(A::FOO); // crashes because of infinity recursion > > ?> > > That isn't a specific problems with arrays: > > class test { > const BAR = 0 + self::FOO; > const FOO = 0 + self::BAR; > } > var_dump(test::BAR); > > just segfaults too because of the exact same issue > Oh... This is really bad. It means we have a general AST evaluation problem. It must be fixed before 5.6 release. I'll try to make another attempt in the evening today or tomorrow. Thanks. Dmitry. > > > I didn't find any useful way to fix it. One of the ideas with following > > hack seemed to work, but it breaks another test > > (Zend/tests/constant_expressions_classes.phpt) > > > > diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c > > index 12f9405..8798737 100644 > > --- a/Zend/zend_ast.c > > +++ b/Zend/zend_ast.c > > @@ -251,10 +251,22 @@ ZEND_API void zend_ast_evaluate(zval *result, > > zend_ast *ast, zend_class_entry *s > > zval_dtor(&op2); > > break; > > case ZEND_CONST: > > - *result = *ast->u.val; > > - zval_copy_ctor(result); > > - if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) { > > - zval_update_constant_ex(&result, 1, scope > > TSRMLS_CC); > > + if (EG(in_execution) && EG(opline_ptr) && > > *EG(opline_ptr) && > > + ((*EG(opline_ptr))->opcode == ZEND_RECV_INIT > || > > + (*EG(opline_ptr))->opcode == > > ZEND_DECLARE_CONST)) { > > + *result = *ast->u.val; > > + zval_copy_ctor(result); > > + if (IS_CONSTANT_TYPE(Z_TYPE_P(result))) { > > + zval_update_constant_ex(&result, > 1, > > scope TSRMLS_CC); > > + } > > + } else { > > + if > (IS_CONSTANT_TYPE(Z_TYPE_P(ast->u.val))) > > { > > + > > zval_update_constant_ex(&ast->u.val, 1, scope TSRMLS_CC); > > + *result = *ast->u.val; > > + } else { > > + *result = *ast->u.val; > > + zval_copy_ctor(result); > > + } > > } > > break; > > case ZEND_BOOL_AND: > > > > I spent few hours trying to find a solution, but failed. May be my ideas > > could lead you to something... > > > > Otherwise, I would recommend to remove this feature from PHP-5.6. > > > > Thanks. Dmitry. > > So, as we see, it's not especially because of arrays, but everytime the > two self-referencing constants are inside an expression of each other, > it'll fail. > > I'm just wondering if we can't somehow deeply copy the asts for opcache > between compile time and run time in pass_two() (If I'm not wrong > pass_two() has some hook for zend extensions?) > > Then we can fix the ast and don't have to take care of opcache at run time > (= when the (dynamic) asts will be evaluated). It'd maybe even be a bit > faster as it then doesn't have to copy so much at run-time. > > Bob > > > On Tue, Jul 22, 2014 at 10:00 AM, Dmitry Stogov wrote: > > > >> Hi Bob, > >> > >> Now I think it's not fixable by design :( > >> > >> I'll try to think about it later today. > >> Could you please collect all related issues. > >> > >> Thanks. Dmitry. > >> > >> > >> On Mon, Jul 21, 2014 at 8:36 PM, Bob Weinand > wrote: > >> > >>> Am 2.7.2014 um 15:43 schrieb Dmitry Stogov : > >>> > >>> I don't have good ideas out of the box and I probably won't be able to > >>> look into this before next week. > >>> > >>> > >>> Hey, I still have no real idea how to solve it without breaking > opcache. > >>> > >>> This one seems to be considered like a blocking bug for 5.6. > >>> > >>> Could you please try to fix this in a sane manner? > >>> > >>> Bob > --bcaec548a8f75c99e804fed864f6--