diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index e5d26096984b..fcb1d02e6069 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2336,10 +2336,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op } goto done; case ZEND_ISSET_ISEMPTY_CV: - if ((opline->extended_value & ZEND_ISEMPTY)) { - // TODO: support for empty() ??? - break; - } if ((opline->result_type & IS_TMP_VAR) && (i + 1) <= end && ((opline+1)->opcode == ZEND_JMPZ diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index eec5434cde74..2f722adef368 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -8349,8 +8349,27 @@ static int zend_jit_isset_isempty_cv(zend_jit_ctx *jit, const zend_op *opline, u uint32_t true_label = -1, false_label = -1; ir_ref end_inputs = IR_UNUSED, true_inputs = IR_UNUSED, false_inputs = IR_UNUSED; - // TODO: support for empty() ??? - ZEND_ASSERT(opline->extended_value != MAY_BE_RESOURCE); + if (opline->extended_value & ZEND_ISEMPTY) { + /* empty($cv) is !$cv, except that an undefined CV doesn't emit a warning. + * Treat UNDEF as NULL: both are falsy and have a type below IS_TRUE. */ + uint8_t branch_opcode; + + if (op1_info & MAY_BE_UNDEF) { + op1_info = (op1_info & ~MAY_BE_UNDEF) | MAY_BE_NULL; + } + if (!smart_branch_opcode) { + branch_opcode = ZEND_BOOL_NOT; + } else if (smart_branch_opcode == ZEND_JMPZ) { + branch_opcode = ZEND_JMPNZ; + } else if (smart_branch_opcode == ZEND_JMPNZ) { + branch_opcode = ZEND_JMPZ; + } else { + ZEND_UNREACHABLE(); + } + /* zend_is_true() may call an object's cast handler. */ + return zend_jit_bool_jmpznz(jit, opline, op1_info, op1_addr, res_addr, + target_label, target_label2, (op1_info & MAY_BE_OBJECT) != 0, branch_opcode, exit_addr); + } if (smart_branch_opcode && !exit_addr) { if (smart_branch_opcode == ZEND_JMPZ) { diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c index 9afe1244a49d..a5b46eb1b25d 100644 --- a/ext/opcache/jit/zend_jit_trace.c +++ b/ext/opcache/jit/zend_jit_trace.c @@ -2074,10 +2074,6 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin ADD_OP1_TRACE_GUARD(); break; case ZEND_ISSET_ISEMPTY_CV: - if ((opline->extended_value & ZEND_ISEMPTY)) { - // TODO: support for empty() ??? - break; - } ADD_OP1_TRACE_GUARD(); break; case ZEND_IN_ARRAY: @@ -5784,10 +5780,6 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, } goto done; case ZEND_ISSET_ISEMPTY_CV: - if ((opline->extended_value & ZEND_ISEMPTY)) { - // TODO: support for empty() ??? - break; - } op1_info = OP1_INFO(); op1_addr = OP1_REG_ADDR(); if (orig_op1_type != IS_UNKNOWN