From ed55c0cc4eaaa316a82018fbb81e56ca9778503e Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 19 Sep 2025 19:02:02 +0200 Subject: [PATCH] Make the call VM read the opline back after interrupts This happened implicitly in the past due to EX(opline) being used - or in the hybrid VM case, the implicit LOAD_OPLINE() happening as part of ZEND_VM_ENTER(). With 76d7c616bb8775520f18456b41121bf934cac391 opline is used standalone and the return value of zend_interrupt_helper_SPEC ignored. Make use of it... Signed-off-by: Bob Weinand --- Zend/zend_vm_execute.h | 4 ++++ Zend/zend_vm_gen.php | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 92e5f327fd08a..33c8e9c223173 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -441,7 +441,11 @@ static zend_vm_opcode_handler_func_t zend_vm_get_opcode_handler_func(uint8_t opc # define ZEND_VM_LEAVE() return (zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT) #endif #define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); +#ifdef ZEND_VM_FP_GLOBAL_REG #define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); +#else +#define ZEND_VM_LOOP_INTERRUPT() opline = (zend_op*)((uintptr_t)zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU) & ~ZEND_VM_ENTER_BIT); +#endif #define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler_func(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_interrupt_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS); diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 01fe2999ab4aa..4ecc44237500a 100755 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -2025,7 +2025,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name) out($f,"# define ZEND_VM_LEAVE() return (zend_op*)((uintptr_t)opline | ZEND_VM_ENTER_BIT)\n"); out($f,"#endif\n"); out($f,"#define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));\n"); + out($f,"#ifdef ZEND_VM_FP_GLOBAL_REG\n"); out($f,"#define ZEND_VM_LOOP_INTERRUPT() zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"); + out($f,"#else\n"); + out($f,"#define ZEND_VM_LOOP_INTERRUPT() opline = (zend_op*)((uintptr_t)zend_interrupt_helper".($spec?"_SPEC":"")."(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU) & ~ZEND_VM_ENTER_BIT);\n"); + out($f,"#endif\n"); if ($kind == ZEND_VM_KIND_HYBRID) { out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler_func(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n"); } else {