From 5380b415a243e538240fbbb92bf020a3719ab927 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 11 Nov 2021 21:14:17 +0300 Subject: [PATCH] JIT: Partially fix handling of exceptions thrown in interrupt handlers --- ext/opcache/jit/zend_jit_disasm_x86.c | 1 + ext/opcache/jit/zend_jit_helpers.c | 17 +++++++++++++++++ ext/opcache/jit/zend_jit_x86.dasc | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/ext/opcache/jit/zend_jit_disasm_x86.c b/ext/opcache/jit/zend_jit_disasm_x86.c index 098742be778..12581658155 100644 --- a/ext/opcache/jit/zend_jit_disasm_x86.c +++ b/ext/opcache/jit/zend_jit_disasm_x86.c @@ -496,6 +496,7 @@ static int zend_jit_disasm_init(void) REGISTER_HELPER(zval_jit_update_constant_ex); #endif REGISTER_HELPER(zend_jit_free_trampoline_helper); + REGISTER_HELPER(zend_jit_exception_in_interrupt_handler_helper); #undef REGISTER_HELPER #ifndef _WIN32 diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 3ddaefd87e7..e2f6fff0ced 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2719,3 +2719,20 @@ static void ZEND_FASTCALL zend_jit_free_trampoline_helper(zend_function *func) zend_string_release_ex(func->common.function_name, 0); zend_free_trampoline(func); } + +static void ZEND_FASTCALL zend_jit_exception_in_interrupt_handler_helper(void) +{ + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); + + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); + } + } +} diff --git a/ext/opcache/jit/zend_jit_x86.dasc b/ext/opcache/jit/zend_jit_x86.dasc index d8f953fe003..52e2388ca37 100644 --- a/ext/opcache/jit/zend_jit_x86.dasc +++ b/ext/opcache/jit/zend_jit_x86.dasc @@ -1768,6 +1768,10 @@ static int zend_jit_interrupt_handler_stub(dasm_State **Dst) | mov aword A1, FP | EXT_CALL zend_interrupt_function, r0 |.endif + | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0 + | je >1 + | EXT_CALL zend_jit_exception_in_interrupt_handler_helper, r0 + |1: | //ZEND_VM_ENTER(); | //execute_data = EG(current_execute_data); | MEM_OP2_2_ZTS mov, FP, aword, executor_globals, current_execute_data, r0