Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:89965 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 40621 invoked from network); 2 Jan 2016 14:12:33 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Jan 2016 14:12:33 -0000 Authentication-Results: pb1.pair.com header.from=laruence@php.net; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=xinchen.h@zend.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 209.85.213.50 as permitted sender) X-PHP-List-Original-Sender: xinchen.h@zend.com X-Host-Fingerprint: 209.85.213.50 mail-vk0-f50.google.com Received: from [209.85.213.50] ([209.85.213.50:35161] helo=mail-vk0-f50.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8D/80-33667-8CAD7865 for ; Sat, 02 Jan 2016 09:12:25 -0500 Received: by mail-vk0-f50.google.com with SMTP id k1so105172614vkb.2 for ; Sat, 02 Jan 2016 06:12:24 -0800 (PST) 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:from:date :message-id:subject:to:cc:content-type; bh=A5Nb7y+uBxXkZiRSPh3frkHYxBVaHEPdPFana6OvFv8=; b=WSYF0IX5jHjWWX9UlKWsEJNsOGDpu+w+ddvr2ypg29dZ3oM6zfYKovFQpIB3ifL00S xeZBcwqoJRyN47sZfutH7w5zFDSfwJJZGcH4jy/QCmRFRWt/mCkcGhn+nRccIzzUUKDD UnLOUPvi02f6AurWz1LerBnhVIvEe37bxGIo1R4EWXVoUvBQ9+ACxISRHnLmt2KNizWF n8c74zsLBqrD+6Zho17oyb6O2pUSqBp10x3reqQFPsqaQzckIvaDWU1pfI/pnEykqmN6 Krld6qfbHH4EVPY61k1rMa0WANkqUljR3CGjzICWUA5wTnd/tNTS27K4WqADSzX5ECZ3 fQpQ== X-Gm-Message-State: ALoCoQlTE9edVCFq9C2lcTPG5VMsan9FTzA4PRCPDcTx8NcJu/iKNWgQtpW5vwHhW7Td6sry0xWscuSGWGgysPZPxLJBu4yOk95ZtHL9MCp1i6OyXwx8id1EacgdmFAZL0biBIVHiQ05DqUEdZoMyuKa7dHGdwFG0kGN+/5+sfGALRmbzaLBJFg6kQ/YVXT5p6r/AMPBanMO X-Received: by 10.31.156.129 with SMTP id f123mr20785014vke.40.1451743941766; Sat, 02 Jan 2016 06:12:21 -0800 (PST) Received: from mail-vk0-f47.google.com (mail-vk0-f47.google.com. [209.85.213.47]) by smtp.gmail.com with ESMTPSA id x128sm10060270vke.14.2016.01.02.06.12.21 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Jan 2016 06:12:21 -0800 (PST) Received: by mail-vk0-f47.google.com with SMTP id a123so73755047vkh.1 for ; Sat, 02 Jan 2016 06:12:21 -0800 (PST) X-Received: by 10.31.149.75 with SMTP id x72mr54160388vkd.81.1451743940936; Sat, 02 Jan 2016 06:12:20 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.199.66 with HTTP; Sat, 2 Jan 2016 06:12:01 -0800 (PST) In-Reply-To: References: Date: Sat, 2 Jan 2016 22:12:01 +0800 X-Gmail-Original-Message-ID: Message-ID: To: Derick Rethans Cc: Nikita Popov , PHP Developers Mailing List , Dmitry Stogov Content-Type: multipart/alternative; boundary=001a11426160e78a9205285a7918 Subject: Re: Line numbers for "finally" From: laruence@php.net (Xinchen Hui) --001a11426160e78a9205285a7918 Content-Type: text/plain; charset=UTF-8 Hey: On Sat, Jan 2, 2016 at 7:59 PM, Derick Rethans wrote: > On Thu, 31 Dec 2015, Nikita Popov wrote: > > > On Thu, Dec 31, 2015 at 1:09 AM, Derick Rethans wrote: > > > > > On Thu, 31 Dec 2015, Nikita Popov wrote: > > > > > > > For PHP 7 only: FAST_CALL always jumps to op1. op2 is not a jmp > > > > addr, it's a try_catch_array offset. For FAST_RET there are no > > > > jump addresses encoded in the opline. It will either jump back to > > > > one past the invoking FAST_CALL (of which there may be multiple), > > > > or (if finally is executed due to an uncaught exception) it will > > > > jump back to the next applicable catch or finally or leave the > > > > function. > > > > > > Hmm, that's more complicated than I thought. How would I fix that > > > code? (PR welcome :D ) > > > > I don't know what you need this for, but maybe you can use the same > > "good enough" approximation we use for our internal control flow > > analysis, namely simply say that FAST_CALL either jumps to op1 or to > > the next instruction, while FAST_RET is treated as a terminator > > instruction (like RETURN). This does not accurately model control > > flow, but it may be sufficient for your purposes. > > I need to analyse every possible branch, and path through the code in > order to do dead code analysis (for which I think your simplified > option works), but also for path coverage, for which I don't think your > algorithm works. Xinchen alluded on IRC: > > 15:21 <@laruence> Derick, it used for calling "finally block" > 15:22 <@laruence> it has the entry opline of finally block as opline->op1 > 15:22 <@laruence> and in the end of finally block ,there always be a > ZEND_FAST_RET opline, which will return to proper address > after finally block codes is executed > > To me that indicates that the FAST_RET can jump back to any location > where FAST_CALL was *called* from (+1)? > > In any case, I think my current code does what you describe, except for > FAST_RET, as that does not act like a RETURN - is there any reason why > my approach wouldn't work? > > Some more observations and questions: > > FAST_CALL: > *jmp1 = XDEBUG_ZNODE_JMP_LINE(opcode.op1, position, base_address); > > - But what do do for *jmp2 - if extended_value is set? if extended_value is set(FROM_FINALLY) that means this finally block is inside another finally block I am not sure what *jmp2 means here? ZEND_FAST_CALL always jmp to one place. but in case FROM_FINALLY it has outer FAST_CALL's opline in op2 . > - I can't come up with PHP code that sets extended_value though. Can you? > try { } finally { try { } finally /* this fast_call will set with FROM_FINALLY*/ {} } > > FAST_RET: > *jmp1 = position + 1; > > - But you indicate that that really should be *jmp1 = XDEBUG_JMP_EXIT? > > - Or, it should jump back to something else? > - But how do I know to which possible opline(s) it is going to jump back > to? - Is there a list of these somewhere? I am afarid there is not, let me try to summary it(I will try to make it clean, but mine poor english :<): ZEND_FAST_CALL opcode is used for set a proper return address for ZEND_FAST_RET. there are two ways can entry a finally block, ZEND_FAST_CALL and ZEND_HANDLE_EXCEPTION: 1) ZEND_FAST_CALL: it set the return address to it's self (it will always follow by a JMP, which will JMP to end of finall block). 2) ZEND_HANDLE_EXCEPTION, if there is catch block then jmp to it(in the end of the catch block there will be a JMP to finally block), if no catch block is matched and there is a finally block, then set fast_call_var->u2.lineno == -1, and stash the EG(exception) into Z_OBJ_P(fast_call_var), then jmp to the finally block. for FAST_RET: in fast_ret, if fast_call_var->u2.lineno != -1, then it means a jmp address, simply jmp to it. if fast_call->u2.lineno == -1, then there must be a un-handle exception(stored in Z_OBJ_P(fast_call_var)), so: if RET_TO_FINALLY(see blow), means there is another finally block needs to be run, jmp to the ZEND_FAST_CALL opline of that finally block, in which opline handle, if opline->extended_value == ZEND_FAST_CALL_FROM_FINALLY(see below) and obviously current Z_OBJ_P(fast_call_var) is set, then goes into the finally block behavior like the way ZEND_HANDLE_EXCEPTION did, which is set the fast_call->u2.lineno to -1, and jmp into the finally block. otherwise, restore the exception, then goes like a new exception is throw(jmp to a CATCH block or leave current function which will result ZEND_HANDLE_EXCEPTION again). - I can't come up with PHP code that sets extended_value here either. > try { try { } finally { } /* this fast_ret will set to RET_TO_CATCH */ } catch () { } try { try { } finally { } /* this fast_ret will set to RET_TO_FINALLY */ } finally { } thanks > Can you? thanks > > cheers, > Derick > -- Xinchen Hui @Laruence http://www.laruence.com/ --001a11426160e78a9205285a7918--