Skip to content

Commit 5009c23

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-15834: Segfault with hook "simple get" cache slot and minimal JIT
2 parents 9ddc25a + f6c2e40 commit 5009c23

File tree

2 files changed

+59
-6
lines changed

2 files changed

+59
-6
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
14251425
uint32_t target_label, target_label2;
14261426
uint32_t op1_info, op1_def_info, op2_info, res_info, res_use_info, op1_mem_info;
14271427
zend_jit_addr op1_addr, op1_def_addr, op2_addr, op2_def_addr, res_addr;
1428-
zend_class_entry *ce;
1428+
zend_class_entry *ce = NULL;
14291429
bool ce_is_instanceof;
14301430
bool on_this;
14311431

@@ -2444,11 +2444,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
24442444
case ZEND_FETCH_OBJ_R:
24452445
case ZEND_FETCH_OBJ_IS:
24462446
case ZEND_FETCH_OBJ_W:
2447-
if (opline->op2_type != IS_CONST
2448-
|| Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
2449-
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
2450-
break;
2451-
}
24522447
ce = NULL;
24532448
ce_is_instanceof = 0;
24542449
on_this = 0;
@@ -2478,6 +2473,11 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
24782473
}
24792474
}
24802475
}
2476+
if (opline->op2_type != IS_CONST
2477+
|| Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
2478+
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
2479+
break;
2480+
}
24812481
if (!zend_jit_fetch_obj(&ctx, opline, op_array, ssa, ssa_op,
24822482
op1_info, op1_addr, 0, ce, ce_is_instanceof, on_this, 0, 0, NULL,
24832483
RES_REG_ADDR(), IS_UNKNOWN,
@@ -2847,6 +2847,36 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
28472847
/* We skip over the DO_FCALL, so decrement call_level ourselves. */
28482848
call_level--;
28492849
}
2850+
break;
2851+
case ZEND_FETCH_OBJ_R:
2852+
if (!zend_jit_handler(&ctx, opline,
2853+
zend_may_throw(opline, ssa_op, op_array, ssa))) {
2854+
goto jit_failure;
2855+
}
2856+
2857+
/* Cache slot is only used for IS_CONST op2, so only that can result in hook fast path. */
2858+
if (opline->op2_type == IS_CONST) {
2859+
if (JIT_G(opt_level) < ZEND_JIT_LEVEL_INLINE) {
2860+
if (opline->op1_type == IS_UNUSED) {
2861+
ce = op_array->scope;
2862+
} else {
2863+
ce = NULL;
2864+
}
2865+
}
2866+
2867+
if (!ce || !(ce->ce_flags & ZEND_ACC_FINAL) || ce->num_hooked_props > 0) {
2868+
/* If a simple hook is called, exit to the VM. */
2869+
ir_ref if_hook_enter = ir_IF(jit_CMP_IP(jit, IR_EQ, opline + 1));
2870+
ir_IF_FALSE(if_hook_enter);
2871+
if (GCC_GLOBAL_REGS) {
2872+
ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit)));
2873+
} else {
2874+
ir_RETURN(ir_CONST_I32(1)); /* ZEND_VM_ENTER */
2875+
}
2876+
ir_IF_TRUE(if_hook_enter);
2877+
}
2878+
}
2879+
28502880
break;
28512881
default:
28522882
if (!zend_jit_handler(&ctx, opline,

ext/opcache/tests/jit/gh15834.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-15834 (Segfault with hook "simple get" cache slot and minimal JIT)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit=1111
7+
--FILE--
8+
<?php
9+
class A {
10+
public $_prop = 1;
11+
public $prop {
12+
get => $this->_prop;
13+
}
14+
}
15+
16+
$a = new A;
17+
for ($i=0;$i<5;$i++) {
18+
echo $a->prop;
19+
$a->_prop++;
20+
}
21+
?>
22+
--EXPECT--
23+
12345

0 commit comments

Comments
 (0)