Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124780 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id B2EC41A00B7 for ; Mon, 5 Aug 2024 17:03:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1722877489; bh=k9EugfEJ5ExuCvMB4ofMbZtEJxYsfLygqw9aZFmfnfA=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=gMkkaMPllbfcRhtLaXl1IjSOH9n0XL44F5Tn3tIN4lqRdexVIcfYYZsoQa0VBFwO1 0wk6vzwSx3LpBiJde4zcgwbN98XwN+OMGlogfB6BtIjNAgScyBO0tg58T5dFiwO88G mSFHdxHKS2dPlTQlEMsR4hN10NRaXklmSgNIVtgkWk0wEukxQ31ReCB09QofDcJcp9 N4Fy+/8lZpI6VCWAas3OsFaTBqR5T7YKye5NHsDj9rBuZfhvVk00YcXL2P1oPau4VX qjm2DqK/wSsNIBtRnivVMEAvOEP83DrJodLD4HLMM2DDdNTucBZ28VvizklsGNA66q 5B8qKTSpUcWIA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id D3984180051 for ; Mon, 5 Aug 2024 17:04:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Mon, 5 Aug 2024 17:04:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1722877384; bh=coHulicDC3Q21C5VnnP8xvYJKYPYpbDde5TgpbvbmiA=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type:from:to:cc:subject:message-id; b=i1ID6AOI/TAjgRQTPxnnBJsmNSgK4QsQ9YRHBvCj0Lm5IFxRDPUoKjkIjYlK8AzgP OVLDflG3tJTza5XToR9Vk3nRJlcyIQ4RqKQBV+iayCXzfnTk25913FNCjPH2fZLHRV CpBP8WPIydNmOg+DxKFCnMAgF1JzRkYkLnhx0tZY3P2MGqUTCN2fC3ecAUPQXNlV8x cbnIXV2UpdEEsWcN2hjWwWBJA4l6SRUfy+yThq0O3Wn4CyaZT3YhfmLny/asdPiD4n F1zBHU/0yQ/crKddCjJd80NVrxf6oPPJfSyrOgpkuPDg/usazrRYZUlSSWe/h8dQHY lBzKpl3dbXnJw== Message-ID: <5943ce1d-fd0d-4efa-be7e-a2df456253b1@bastelstu.be> Date: Mon, 5 Aug 2024 19:03:03 +0200 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Subject: Re: [PHP-DEV] [RFC] Transform exit() from a language construct into a standard function To: Derick Rethans Cc: Ilija Tovilo , PHP internals References: <9c69992e-2962-476d-baca-aa51bdd0f1f7@bastelstu.be> <67f2f610-dca8-e8ce-a513-2aef0fcf2698@php.net> <9492f9e2-7390-de77-b524-cd84ff452157@php.net> Content-Language: en-US In-Reply-To: <9492f9e2-7390-de77-b524-cd84ff452157@php.net> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=C3=BCsterhus?=) Hi On 8/2/24 13:39, Derick Rethans wrote: > It's for that, but also for path/branch analysis, as I just wrote above. > > Having an EXIT opcode, instead of a function call is a clean indicator > that a path (and branch) ends here. > > With a function call, I have no idea about whether a path ends there. If the function called the return type `never` then you know that the path ends there. As the `exit()` function cannot be overridden, you are even guaranteed that any call to a function called `exit()` is the real `exit()` function. Either the script exits or the function throws a TypeError. The latter is true even with current PHP versions as demonstrated by this example script: >> If there is a function call to a function with a 'never' return >>> type, then that function will potentially throw, or exit. >>> >>> But that's not relevant for the analysis, as these userland >>> functions will have their own oparrays with their entry and exit >>> points. >> >> The compiler has the function table available. It is used to optimize >> specific functions into dedicated Opcodes. Thus you should be able to >> look up the function within the function table and then check its >> return type. > > Yes, but functions that call exit are not required to have the 'never' > return type, so that's not useful. The `exit()` function as implemented in Gina's PR has the `never` return type, thus the situation is no worse than the current situation. Instead of checking for the ZEND_EXIT opcode, you check for a function call and if the function has the `never` return type (which `exit()` is guaranteed to have), then you can treat it as a path ending there. Or you can just hardcode a check for a call to the `exit()` function, as outlined above. >>>>> It also breaks my "do tasks on ZEND_EXIT" with the profiler. It >>>>> is used to always write the closing profiling footer to the >>>>> files. Without me being able to overload thati opcode, data >>>>> would not be complete. I even have two bugs (with tests) for >>>>> this: >>>>> >>>>> - https://bugs.xdebug.org/68 - https://bugs.xdebug.org/631 >>>> >>>> Likewise, how is ZEND_EXIT special here? How does it work >>>> differently than a script that runs to completion without calling >>>> exit(); or a script that fails, e.g. due to an uncaught exception >>>> or due to reaching the memory limit? >>> >>> I overload EXIT so that I can flush the profile file before the >>> script actually fully ends. This is useful for testing through phpt >>> tests. It looks like I might be able to use existing function >>> observers for this, but I haven't fully made that work yet. >> >> Why does the EXIT opcode need to be special-cased here? What if a >> script dies due to an uncaught Exception, due to exceeding the memory >> limit, or simply terminates by successfully running until the finish, >> without explicitly calling exit()? > > It's not important for normal functionality as the execution still ends > there. It's useful for *testing* as I said before. It was not clear to me that this is only relevant for testing purposes. I don't understand why you would need the special handling for testing purposes, but as outlined above you can just hardcode a check for a call to the `exit()` function if the tests cannot use the regular script end for some reason. Best regards Tim Düsterhus