diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 2007f28e91fd2..00f66676f39fd 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -231,6 +231,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D); bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D); void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D); +void ZEND_FASTCALL zend_jit_undefined_long_key_ex(zend_long key EXECUTE_DATA_DC); void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D); zend_constant* ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags); diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 4b31f2e07ae71..8d95ad5ea0c6c 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -3024,6 +3024,7 @@ static void zend_jit_setup_disasm(void) REGISTER_HELPER(zend_jit_verify_return_slow); REGISTER_HELPER(zend_jit_deprecated_helper); REGISTER_HELPER(zend_jit_undefined_long_key); + REGISTER_HELPER(zend_jit_undefined_long_key_ex); REGISTER_HELPER(zend_jit_undefined_string_key); REGISTER_HELPER(zend_jit_copy_extra_args_helper); REGISTER_HELPER(zend_jit_vm_stack_free_args_helper); @@ -11716,6 +11717,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, if (!op2_loaded) { // JIT: hval = Z_LVAL_P(dim); h = jit_Z_LVAL(jit, op2_addr); + op2_loaded = 1; } if (packed_loaded) { ref = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(_zend_hash_index_find), ht_ref, h); @@ -11765,6 +11767,7 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, if (!op2_loaded) { // JIT: hval = Z_LVAL_P(dim); h = jit_Z_LVAL(jit, op2_addr); + op2_loaded = 1; } if (packed_loaded) { ref = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(_zend_hash_index_find), ht_ref, h); @@ -11808,7 +11811,19 @@ static int zend_jit_fetch_dimension_address_inner(zend_jit_ctx *jit, // JIT: zend_error(E_WARNING,"Undefined array key " ZEND_LONG_FMT, hval); // JIT: retval = &EG(uninitialized_zval); jit_SET_EX_OPLINE(jit, opline); - ir_CALL(IR_VOID, jit_STUB_FUNC_ADDR(jit, jit_stub_undefined_offset, IR_FASTCALL_FUNC)); + if (Z_MODE(op2_addr) == IS_REG) { + if (!op2_loaded) { + // JIT: hval = Z_LVAL_P(dim); + h = jit_Z_LVAL(jit, op2_addr); + } + if (GCC_GLOBAL_REGS) { + ir_CALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key_ex), h); + } else { + ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key_ex), h, jit_FP(jit)); + } + } else { + ir_CALL(IR_VOID, jit_STUB_FUNC_ADDR(jit, jit_stub_undefined_offset, IR_FASTCALL_FUNC)); + } ir_END_list(*end_inputs); break; case BP_VAR_IS: diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index e9cdeeab9865a..d93e5fce94780 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -210,6 +210,15 @@ void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D) ZVAL_NULL(result); } +void ZEND_FASTCALL zend_jit_undefined_long_key_ex(zend_long key EXECUTE_DATA_DC) +{ + const zend_op *opline = EX(opline); + zval *result = EX_VAR(opline->result.var); + + zend_error(E_WARNING, "Undefined array key " ZEND_LONG_FMT, key); + ZVAL_NULL(result); +} + void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D) { const zend_op *opline = EX(opline); diff --git a/ext/opcache/tests/jit/gh15972.phpt b/ext/opcache/tests/jit/gh15972.phpt new file mode 100644 index 0000000000000..11d234f0c96a5 --- /dev/null +++ b/ext/opcache/tests/jit/gh15972.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-15972 (Assertion failure in ext/opcache/jit/zend_jit_vm_helpers.c with function JIT) +--EXTENSIONS-- +opcache +--FILE-- + +DONE +--EXPECT-- +DONE