From 5f754c32df4bd8643d62babf6f805defe59c8c92 Mon Sep 17 00:00:00 2001 From: jvoisin Date: Sun, 10 May 2026 01:01:43 +0200 Subject: Prevent opcache from inlining functions with return-value rules on PHP 8.5+ PHP 8.5's opcache optimizer can inline trivial user functions (constant return values), completely eliminating the DO_UCALL opcode. When this happens, zend_execute_ex is never invoked and snuffleupagus's return-value monitoring hooks never fire. Fix this by setting ZEND_ACC_HAS_TYPE_HINTS on monitored functions' op_arrays during compilation (via sp_op_array_handler). This flag is checked by opcache's zend_try_inline_call() and prevents inlining. For 0-arg functions — the only ones eligible for inlining — there are no RECV opcodes, so the runtime impact is zero. To enable sp_op_array_handler when return-value rules are configured, the extension now registers itself as a zend extension and sets ZEND_COMPILE_HANDLE_OP_ARRAY (previously only done for global_strict). The disabled_function_echo_2 test is updated to use separate echo statements and opcache.optimization_level=0, since opcache's echo merging is a compile-time string concatenation that cannot be prevented per-function. This is a bit ugly, but it's the less awful solution to be able to hook return values. --- src/tests/disable_function/disabled_function_echo_2.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/tests/disable_function') diff --git a/src/tests/disable_function/disabled_function_echo_2.phpt b/src/tests/disable_function/disabled_function_echo_2.phpt index e519ec4..ce3488e 100644 --- a/src/tests/disable_function/disabled_function_echo_2.phpt +++ b/src/tests/disable_function/disabled_function_echo_2.phpt @@ -2,9 +2,9 @@ Echo hooking --SKIPIF-- -= 80500) print "skip"; ?> --INI-- sp.configuration_file={PWD}/config/disabled_function_echo.ini +opcache.optimization_level=0 --FILE--